ZQuest Classic Coverage Report


Directory: src/
File: src/zc/maps.cpp
Date: 2025-09-03 02:14:11
Exec Total Coverage
Lines: 4060 5062 80.2%
Functions: 290 328 88.4%
Branches: 3119 5100 61.2%

Line Branch Exec Source
1 #include "base/combo.h"
2 #include "base/handles.h"
3 #include "base/util.h"
4 #include "base/zdefs.h"
5 #include "base/general.h"
6 #include <cstring>
7 #include <assert.h>
8 #include <math.h>
9 #include <vector>
10 #include <deque>
11 #include <string>
12 #include <set>
13 #include <array>
14 #include <sstream>
15 using std::set;
16
17 #include "base/qrs.h"
18 #include "base/dmap.h"
19 #include "base/mapscr.h"
20 #include "base/misctypes.h"
21 #include "base/initdata.h"
22 #include "zc/maps.h"
23 #include "zc/zelda.h"
24 #include "zc/zc_ffc.h"
25 #include "tiles.h"
26 #include "sprite.h"
27 #include "gui/jwin.h"
28 #include "base/zsys.h"
29 #include "subscr.h"
30 #include "zc/zc_subscr.h"
31 #include "zc/hero.h"
32 #include "zc/guys.h"
33 #include "zc/ffscript.h"
34 #include "drawing.h"
35 #include "zc/combos.h"
36 #include "zc/replay.h"
37 #include "slopes.h"
38 #include "particles.h"
39 #include <fmt/format.h>
40 #include "zc/render.h"
41 #include "iter.h"
42 #include <ranges>
43
44 // All the temporary screens (and their layers) for the currently loaded map.
45 static mapscr* temporary_screens[136*7];
46 // Set by load_region.
47 static bool screen_in_current_region[136];
48 414 static rpos_handle_t current_region_rpos_handles[136*7];
49 static bool current_region_rpos_handles_dirty;
50 static int current_region_screen_count;
51 static std::pair<const rpos_handle_t*, int> current_region_rpos_handles_scr[136];
52
53 viewport_t viewport;
54 static int viewport_sprite_uid;
55 ViewportMode viewport_mode;
56 int world_w, world_h;
57 int region_scr_dx, region_scr_dy;
58 int region_scr_count;
59 rpos_t region_max_rpos;
60 int region_num_rpos;
61 region_t cur_region, scrolling_region;
62
63 414 maze_state_t maze_state;
64 int scrolling_maze_last_solved_screen;
65
66 575 void maps_init_game_vars()
67 {
68 575 viewport = {};
69 575 viewport_mode = ViewportMode::CenterAndBound;
70 575 viewport_sprite_uid = 1;
71 575 currscr_for_passive_subscr = -1;
72 575 }
73
74 static region_ids_t current_region_ids;
75
76 14616166 static bool is_a_region(int map, int scr)
77 {
78 14616166 return get_region_id(map, scr) != 0;
79 }
80
81 2232 static bool is_same_region_id(int region_origin_scr, int map, int scr)
82 {
83
2/2
✓ Branch 0 taken 772 times.
✓ Branch 1 taken 1460 times.
2232 if (!is_a_region(map, scr)) return false;
84 1460 int region_id = get_region_id(map, region_origin_scr);
85
1/2
✓ Branch 0 taken 1460 times.
✗ Branch 1 not taken.
1460 return region_id && region_id == get_region_id(map, scr);
86 2232 }
87
88 137745940 bool is_in_current_region(int map, int screen)
89 {
90
5/6
✓ Branch 0 taken 137744367 times.
✓ Branch 1 taken 1573 times.
✓ Branch 2 taken 137744367 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12213 times.
✓ Branch 5 taken 137732154 times.
137745940 return map == cur_map && screen >= 0 && screen < 128 && screen_in_current_region[screen];
91 }
92
93 181529104 bool is_in_current_region(int screen)
94 {
95
2/2
✓ Branch 0 taken 2993339 times.
✓ Branch 1 taken 178535765 times.
181529104 return screen < 128 && screen_in_current_region[screen];
96 }
97
98 29474531 bool is_in_current_region(mapscr* scr)
99 {
100
4/4
✓ Branch 0 taken 29459841 times.
✓ Branch 1 taken 14690 times.
✓ Branch 2 taken 462663 times.
✓ Branch 3 taken 28997178 times.
29474531 return scr->map == cur_map && scr->screen < 128 && screen_in_current_region[scr->screen];
101 }
102
103 bool is_in_scrolling_region(int screen)
104 {
105 if (!screenscrolling) return false;
106
107 int x = screen % 16;
108 int y = screen / 16;
109 return
110 scrolling_region.origin_screen_x >= x && scrolling_region.origin_screen_x < x + scrolling_region.screen_width &&
111 scrolling_region.origin_screen_y >= y && scrolling_region.origin_screen_y < y + scrolling_region.screen_height;
112 }
113
114 9098471039 bool is_in_scrolling_region()
115 {
116 9098471039 return cur_region.screen_count > 1;
117 }
118
119 76829448 bool is_extended_height_mode()
120 {
121
2/2
✓ Branch 0 taken 76579314 times.
✓ Branch 1 taken 250134 times.
76829448 return cur_region.screen_height > 1 && (DMaps[cur_dmap].flags & dmfEXTENDEDVIEWPORT);
122 }
123
124 // Returns 0 if this is not a region.
125 15658208 int get_region_id(int map, int screen)
126 {
127
2/2
✓ Branch 0 taken 401435 times.
✓ Branch 1 taken 15256773 times.
15658208 if (screen >= 128) return 0;
128
2/2
✓ Branch 0 taken 15255673 times.
✓ Branch 1 taken 1100 times.
15256773 if (map == cur_region.map) return current_region_ids[screen];
129
130 1100 return Regions[map].get_region_id(screen);
131 15658208 }
132
133 982758 int get_current_region_id()
134 {
135 982758 return get_region_id(cur_map, cur_screen);
136 }
137
138 64215 void calculate_region(int map, int screen, region_t& region, int& region_scr_dx, int& region_scr_dy)
139 {
140 64215 region.map = map;
141
142
3/4
✓ Branch 0 taken 274 times.
✓ Branch 1 taken 63941 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 274 times.
64215 if (!(is_a_region(map, screen)) || screen >= 0x80)
143 {
144 63941 region.region_id = 0;
145 63941 region.origin_screen = screen;
146 63941 region.origin_screen_x = screen % 16;
147 63941 region.origin_screen_y = screen / 16;
148 63941 region.screen_width = 1;
149 63941 region.screen_height = 1;
150 63941 region.screen_count = 1;
151 63941 region.width = 256;
152 63941 region.height = 176;
153 63941 region_scr_dx = 0;
154 63941 region_scr_dy = 0;
155 63941 return;
156 }
157
158 274 int input_scr_x = screen % 16;
159 274 int input_scr_y = screen / 16;
160
161 // For the given screen, find the top-left corner of its region.
162 274 int origin_scr_x = input_scr_x;
163 274 int origin_scr_y = input_scr_y;
164 274 int origin_scr = screen;
165
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 372 times.
434 while (origin_scr_x > 0)
166 {
167
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 160 times.
372 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x - 1, origin_scr_y))) break;
168 160 origin_scr_x--;
169 }
170
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 414 times.
508 while (origin_scr_y > 0)
171 {
172
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 234 times.
414 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, origin_scr_y - 1))) break;
173 234 origin_scr_y--;
174 }
175 274 origin_scr = map_scr_xy_to_index(origin_scr_x, origin_scr_y);
176
177 // Now find the bottom-right corner.
178 274 int region_scr_right = origin_scr_x;
179
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 614 times.
642 while (region_scr_right < 15)
180 {
181
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 368 times.
614 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(region_scr_right + 1, origin_scr_y))) break;
182 368 region_scr_right++;
183 }
184 274 int region_scr_bottom = origin_scr_y;
185
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 832 times.
856 while (region_scr_bottom < 7)
186 {
187
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 582 times.
832 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, region_scr_bottom + 1))) break;
188 582 region_scr_bottom++;
189 }
190
191 274 region.region_id = get_region_id(map, origin_scr);
192 274 region.origin_screen = origin_scr;
193 274 region.origin_screen_x = origin_scr_x;
194 274 region.origin_screen_y = origin_scr_y;
195 274 region.screen_width = region_scr_right - origin_scr_x + 1;
196 274 region.screen_height = region_scr_bottom - origin_scr_y + 1;
197 274 region.screen_count = region.screen_width * region.screen_height;
198 274 region.width = 256 * region.screen_width;
199 274 region.height = 176 * region.screen_height;
200 274 region_scr_dx = input_scr_x - origin_scr_x;
201 274 region_scr_dy = input_scr_y - origin_scr_y;
202
203 DCHECK_RANGE_INCLUSIVE(region.screen_width, 0, 16);
204 DCHECK_RANGE_INCLUSIVE(region.screen_height, 0, 8);
205 64215 }
206
207 35854 void load_region(int dmap, int screen)
208 {
209 35854 clear_temporary_screens();
210
211 35854 int map = DMaps[dmap].map;
212 35854 current_region_ids = Regions[map].get_all_region_ids();
213
214 35854 calculate_region(map, screen, cur_region, region_scr_dx, region_scr_dy);
215 35854 cur_screen = cur_region.origin_screen;
216 35854 world_w = cur_region.width;
217 35854 world_h = cur_region.height;
218 35854 region_scr_count = cur_region.screen_count;
219 35854 region_max_rpos = (rpos_t)(cur_region.screen_count*176 - 1);
220 35854 region_num_rpos = cur_region.screen_count*176;
221 35854 scrolling_maze_last_solved_screen = 0;
222
223 35854 memset(screen_in_current_region, false, sizeof(screen_in_current_region));
224
2/2
✓ Branch 0 taken 36088 times.
✓ Branch 1 taken 35854 times.
71942 for (int x = 0; x < cur_region.screen_width; x++)
225 {
226
2/2
✓ Branch 0 taken 37098 times.
✓ Branch 1 taken 36088 times.
73186 for (int y = 0; y < cur_region.screen_height; y++)
227 {
228 37098 int screen = cur_screen + x + y*16;
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37098 times.
37098 if (screen < 136)
230 {
231 37098 screen_in_current_region[screen] = true;
232 37098 }
233 37098 }
234 36088 }
235
236 35854 mark_current_region_handles_dirty();
237 35854 }
238
239 35854 static void prepare_current_region_handles()
240 {
241 35854 current_region_rpos_handles_dirty = false;
242 35854 current_region_screen_count = 0;
243
2/2
✓ Branch 0 taken 36202 times.
✓ Branch 1 taken 35854 times.
72056 for (int y = 0; y < cur_region.screen_height; y++)
244 {
245
2/2
✓ Branch 0 taken 37098 times.
✓ Branch 1 taken 36202 times.
73300 for (int x = 0; x < cur_region.screen_width; x++)
246 {
247 37098 int screen = cur_screen + x + y*16;
248 37098 int index_start = current_region_screen_count;
249
2/2
✓ Branch 0 taken 37098 times.
✓ Branch 1 taken 259686 times.
296784 for (int layer = 0; layer <= 6; layer++)
250 {
251 259686 mapscr* scr = get_scr_layer(screen, layer);
252
2/2
✓ Branch 0 taken 86175 times.
✓ Branch 1 taken 173511 times.
259686 if (!scr->is_valid())
253 {
254
1/2
✓ Branch 0 taken 173511 times.
✗ Branch 1 not taken.
173511 if (layer == 0) break;
255 173511 continue;
256 }
257
258 86175 rpos_t base_rpos = POS_TO_RPOS(0, get_region_relative_dx(screen), get_region_relative_dy(screen));
259 86175 current_region_rpos_handles[current_region_screen_count] = {scr, screen, layer, base_rpos, 0};
260 86175 current_region_screen_count += 1;
261 86175 }
262
263 37098 int num_handles_for_scr = current_region_screen_count - index_start;
264 37098 current_region_rpos_handles_scr[screen] = {&current_region_rpos_handles[index_start], num_handles_for_scr};
265 37098 }
266 36202 }
267 35854 }
268
269 1782246915 std::tuple<const rpos_handle_t*, int> get_current_region_handles()
270 {
271 DCHECK(!current_region_rpos_handles_dirty);
272 1782246915 return {current_region_rpos_handles, current_region_screen_count};
273 }
274
275 11056526 std::tuple<const rpos_handle_t*, int> get_current_region_handles(mapscr* scr)
276 {
277 DCHECK(!current_region_rpos_handles_dirty);
278
2/4
✓ Branch 0 taken 11056526 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11056526 times.
11056526 if (scr == special_warp_return_scr || current_region_rpos_handles_dirty)
279 return {nullptr, 0};
280
281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11056526 times.
11056526 if (cur_screen >= 0x80)
282 {
283 DCHECK(scr == origin_scr);
284 return {nullptr, 0};
285 }
286
287 DCHECK(is_in_current_region(scr));
288 11056526 return current_region_rpos_handles_scr[scr->screen];
289 11056526 }
290
291 35854 void mark_current_region_handles_dirty()
292 {
293 35854 current_region_rpos_handles_dirty = true;
294 35854 }
295
296 64941 void delete_temporary_screens(mapscr** screens)
297 {
298
2/2
✓ Branch 0 taken 61823832 times.
✓ Branch 1 taken 64941 times.
61888773 for (int i = 0; i < 136*7; i++)
299 {
300
2/2
✓ Branch 0 taken 255689 times.
✓ Branch 1 taken 61568143 times.
61823832 if (!screens[i])
301 61568143 continue;
302
303 255689 mapscr* scr = screens[i];
304 255689 int num_ffcs = scr->numFFC();
305
2/2
✓ Branch 0 taken 7619480 times.
✓ Branch 1 taken 255689 times.
7875169 for (int i = 0; i < num_ffcs; i++)
306 {
307 7619480 sprite* ffc = &scr->ffcs[i];
308
2/2
✓ Branch 0 taken 7617623 times.
✓ Branch 1 taken 1857 times.
7619480 if (ffc->uid)
309 1857 FFCore.release_sprite_owned_objects(ffc->uid);
310 7619480 }
311
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 255689 times.
255689 delete scr;
312 255689 screens[i] = NULL;
313 255689 }
314 64941 }
315
316 36991 void clear_temporary_screens()
317 {
318 36991 delete_temporary_screens(temporary_screens);
319 36991 origin_scr = nullptr;
320 36991 hero_scr = nullptr;
321 36991 }
322
323 27954 std::vector<mapscr*> take_temporary_scrs()
324 {
325
1/2
✓ Branch 0 taken 27954 times.
✗ Branch 1 not taken.
27954 std::vector<mapscr*> screens(temporary_screens, temporary_screens + 136*7);
326
2/2
✓ Branch 0 taken 27954 times.
✓ Branch 1 taken 26612208 times.
26640162 for (int i = 0; i < 136*7; i++)
327 26612208 temporary_screens[i] = nullptr;
328
329 27954 return screens;
330
1/2
✓ Branch 0 taken 27954 times.
✗ Branch 1 not taken.
27954 }
331
332 14550079 void calculate_viewport(viewport_t& viewport, int dmap, int screen, int world_w, int world_h, int x, int y)
333 {
334 // TODO: In future, maybe add x/y centering offsets to zscript (Viewport->TargetXOffset/Viewport->TargetYOffset).
335
336
2/2
✓ Branch 0 taken 14503497 times.
✓ Branch 1 taken 46582 times.
14550079 bool extended_height_mode = (DMaps[dmap].flags & dmfEXTENDEDVIEWPORT) && world_h > 176;
337 14550079 viewport.w = 256;
338 14550079 viewport.h = 176 + (extended_height_mode ? 56 : 0);
339
340
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 14549719 times.
14550079 if (viewport_mode == ViewportMode::Script)
341 360 return;
342
343
2/2
✓ Branch 0 taken 46162 times.
✓ Branch 1 taken 14503557 times.
14549719 if (!is_a_region(DMaps[dmap].map, screen))
344 {
345 14503557 viewport.x = 0;
346 14503557 viewport.y = 0;
347 14503557 }
348
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46162 times.
46162 else if (viewport_mode == ViewportMode::CenterAndBound)
349 {
350 // Clamp the viewport to the edges of the region.
351
6/6
✓ Branch 0 taken 8568 times.
✓ Branch 1 taken 37594 times.
✓ Branch 2 taken 6788 times.
✓ Branch 3 taken 39374 times.
✓ Branch 4 taken 8568 times.
✓ Branch 5 taken 30806 times.
46162 viewport.x = CLAMP(0, world_w - viewport.w, x - viewport.w/2);
352
6/6
✓ Branch 0 taken 11856 times.
✓ Branch 1 taken 34306 times.
✓ Branch 2 taken 5650 times.
✓ Branch 3 taken 40512 times.
✓ Branch 4 taken 11856 times.
✓ Branch 5 taken 28656 times.
46162 viewport.y = CLAMP(0, world_h - viewport.h, y - viewport.h/2);
353 46162 }
354 else if (viewport_mode == ViewportMode::Center)
355 {
356 viewport.x = x - viewport.w/2;
357 viewport.y = y - viewport.h/2;
358 }
359 14550079 }
360
361 14549568 sprite* get_viewport_sprite()
362 {
363 14549568 sprite* spr = sprite::getByUID(viewport_sprite_uid);
364
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 14549562 times.
14549568 if (!spr)
365 {
366 6 viewport_sprite_uid = 1; // Hero uid.
367 6 spr = &Hero;
368 6 }
369
370 14549568 return spr;
371 }
372
373 6 void set_viewport_sprite(sprite* spr)
374 {
375 6 viewport_sprite_uid = spr->uid;
376 6 }
377
378 14521614 void update_viewport()
379 {
380 14521614 sprite* spr = get_viewport_sprite();
381 14521614 int x = spr->x + spr->txsz*16/2;
382 14521614 int y = spr->y + spr->tysz*16/2;
383 14521614 calculate_viewport(viewport, cur_dmap, cur_screen, world_w, world_h, x, y);
384 14521614 }
385
386 // TODO: should add a moveflag to sprites to configure the size of this rect (or effectively disable
387 // freezing if the rect returns is large enough). See:
388 // https://discord.com/channels/876899628556091432/1358483603700449581
389 // https://discord.com/channels/876899628556091432/1130384911983980554
390 //
391 85866675 viewport_t get_sprite_freeze_rect()
392 {
393 85866675 viewport_t freeze_rect = viewport;
394 85866675 int tile_buffer = 3;
395 85866675 freeze_rect.w += 16 * tile_buffer * 2;
396 85866675 freeze_rect.h += 16 * tile_buffer * 2;
397 85866675 freeze_rect.x -= 16 * tile_buffer;
398 85866675 freeze_rect.y -= 16 * tile_buffer;
399 85866675 return freeze_rect;
400 }
401
402 4722 mapscr* determine_hero_screen_from_coords()
403 {
404 4722 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
405 4722 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
406 4722 int dx = x / 256;
407 4722 int dy = y / 176;
408 4722 return get_scr(cur_screen + dx + dy * 16);
409 }
410
411 26924 bool edge_of_region(direction dir)
412 {
413
2/2
✓ Branch 0 taken 26844 times.
✓ Branch 1 taken 80 times.
26924 if (!is_in_scrolling_region()) return true;
414
415 80 int screen_x = Hero.current_screen % 16;
416 80 int screen_y = Hero.current_screen / 16;
417
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2 times.
80 if (dir == up) screen_y -= 1;
418
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 10 times.
80 if (dir == down) screen_y += 1;
419
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 30 times.
80 if (dir == left) screen_x -= 1;
420
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 38 times.
80 if (dir == right) screen_x += 1;
421
4/8
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
80 if (screen_x < 0 || screen_x > 16 || screen_y < 0 || screen_y > 8) return true;
422 80 return !is_in_current_region(map_scr_xy_to_index(screen_x, screen_y));
423 26924 }
424
425 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
426 // Coordinates are clamped to the world bounds.
427 323831834 int get_screen_for_world_xy(int x, int y)
428 {
429
2/2
✓ Branch 0 taken 300630678 times.
✓ Branch 1 taken 23201156 times.
323831834 if (!is_in_scrolling_region())
430 300630678 return cur_screen;
431
432 23201156 int dx = std::clamp(x, 0, world_w - 1) / 256;
433 23201156 int dy = std::clamp(y, 0, world_h - 1) / 176;
434 23201156 int origin_screen_x = cur_screen % 16;
435 23201156 int origin_screen_y = cur_screen / 16;
436 23201156 int scr_x = origin_screen_x + dx;
437 23201156 int scr_y = origin_screen_y + dy;
438 23201156 return map_scr_xy_to_index(scr_x, scr_y);
439 323831834 }
440
441 32476836 int get_screen_for_rpos(rpos_t rpos)
442 {
443 32476836 int origin_screen_x = cur_screen % 16;
444 32476836 int origin_screen_y = cur_screen / 16;
445 32476836 int screen = static_cast<int32_t>(rpos) / 176;
446 32476836 int scr_x = origin_screen_x + screen%cur_region.screen_width;
447 32476836 int scr_y = origin_screen_y + screen/cur_region.screen_width;
448 32476836 return map_scr_xy_to_index(scr_x, scr_y);
449 }
450
451 776461867 rpos_handle_t get_rpos_handle(rpos_t rpos, int layer)
452 {
453 DCHECK_LAYER_ZERO_INDEX(layer);
454
2/2
✓ Branch 0 taken 744122991 times.
✓ Branch 1 taken 32338876 times.
776461867 if (!is_in_scrolling_region())
455 744122991 return {get_scr_layer(cur_screen, layer), cur_screen, layer, rpos, RPOS_TO_POS(rpos)};
456 32338876 int screen = get_screen_for_rpos(rpos);
457 32338876 mapscr* scr = get_scr_layer(screen, layer);
458 32338876 return {scr, screen, layer, rpos, RPOS_TO_POS(rpos)};
459 776461867 }
460
461 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
462 // Coordinates are clamped to the world bounds.
463 3478304386 rpos_handle_t get_rpos_handle_for_world_xy(int x, int y, int layer)
464 {
465 3478304386 x = std::clamp(x, 0, world_w - 1);
466 3478304386 y = std::clamp(y, 0, world_h - 1);
467
468 DCHECK_LAYER_ZERO_INDEX(layer);
469
2/2
✓ Branch 0 taken 3450587140 times.
✓ Branch 1 taken 27717246 times.
3478304386 if (!is_in_scrolling_region())
470 {
471 3450587140 int pos = COMBOPOS(x, y);
472 3450587140 return {get_scr_layer(cur_screen, layer), cur_screen, layer, (rpos_t)pos, pos};
473 }
474 27717246 return get_rpos_handle(COMBOPOS_REGION(x, y), layer);
475 3478304386 }
476
477 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
478 1926 rpos_handle_t get_rpos_handle_for_screen(int screen, int layer, int pos)
479 {
480 DCHECK_LAYER_ZERO_INDEX(layer);
481 1926 return {get_scr_layer(screen, layer), screen, layer, POS_TO_RPOS(pos, screen), pos};
482 }
483
484 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
485 // Use this instead of the other `get_pos_handle_for_screen` if you already have a reference to the screen.
486 62247 rpos_handle_t get_rpos_handle_for_scr(mapscr* scr, int layer, int pos)
487 {
488 DCHECK_LAYER_ZERO_INDEX(layer);
489 62247 return {scr, scr->screen, layer, POS_TO_RPOS(pos, scr->screen), pos};
490 }
491
492 25183265 void change_rpos_handle_layer(rpos_handle_t& rpos_handle, int layer)
493 {
494 DCHECK_LAYER_ZERO_INDEX(layer);
495 25183265 rpos_handle.layer = layer;
496 25183265 rpos_handle.scr = get_scr_layer(rpos_handle.screen, layer);
497 25183265 }
498
499 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
500 // Coordinates are clamped to the world bounds.
501 52808 combined_handle_t get_combined_handle_for_world_xy(int x, int y, int layer)
502 {
503 DCHECK_LAYER_ZERO_INDEX(layer);
504
505 52808 x = std::clamp(x, 0, world_w - 1);
506 52808 y = std::clamp(y, 0, world_h - 1);
507
508 52808 auto maybe_ffc_handle = getFFCAt(x, y);
509
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (maybe_ffc_handle)
510 return maybe_ffc_handle.value();
511
512 52808 auto rpos = COMBOPOS_REGION_B(x, y);
513
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (rpos == rpos_t::None)
514 return rpos_handle_t();
515 52808 return get_rpos_handle(rpos, layer);
516 52808 }
517
518 // These functions all return _temporary_ screens. Any modifications made to them (either by the engine
519 // directly or via zscript) only last until the next area is loaded (via loadscr).
520
521 // Returns the screen containing the (x, y) world position.
522 1616707428 mapscr* get_scr_for_world_xy(int x, int y)
523 {
524 // Quick path, but should work the same without.
525
2/2
✓ Branch 0 taken 1605580676 times.
✓ Branch 1 taken 11126752 times.
1616707428 if (!is_in_scrolling_region()) return origin_scr;
526 11126752 return get_scr(get_screen_for_world_xy(x, y));
527 1616707428 }
528
529 24512760 mapscr* get_scr_for_rpos(rpos_t rpos)
530 {
531 // Quick path, but should work the same without.
532
2/2
✓ Branch 0 taken 24374814 times.
✓ Branch 1 taken 137946 times.
24512760 if (!is_in_scrolling_region()) return origin_scr;
533 137946 return get_scr(get_screen_for_rpos(rpos));
534 24512760 }
535
536 14 mapscr* get_scr_for_rpos_layer(rpos_t rpos, int layer)
537 {
538 14 return get_scr_layer(get_screen_for_rpos(rpos), layer);
539 }
540
541 // Note: layer=0 is the base screen, 1 is the first layer, etc.
542 2308655141 mapscr* get_scr_for_world_xy_layer(int x, int y, int layer)
543 {
544 DCHECK_LAYER_ZERO_INDEX(layer);
545
2/2
✓ Branch 0 taken 2297235143 times.
✓ Branch 1 taken 11419998 times.
2308655141 if (!is_in_scrolling_region()) return get_scr_layer(cur_screen, layer);
546
2/2
✓ Branch 0 taken 708934 times.
✓ Branch 1 taken 10711064 times.
11419998 return layer == 0 ?
547 708934 get_scr_for_world_xy(x, y) :
548 10711064 get_scr_layer(get_screen_for_world_xy(x, y), layer);
549 2308655141 }
550
551 1833450445 int get_region_screen_offset(int screen)
552 {
553 1833450445 return get_region_relative_dx(screen) + get_region_relative_dy(screen) * cur_region.screen_width;
554 }
555
556 654676699 int get_screen_for_region_index_offset(int offset)
557 {
558 654676699 int scr_dx = offset % cur_region.screen_width;
559 654676699 int scr_dy = offset / cur_region.screen_width;
560 654676699 int screen = cur_screen + scr_dx + scr_dy*16;
561 654676699 return screen;
562 }
563
564 654492862 mapscr* get_scr_for_region_index_offset(int offset)
565 {
566 654492862 int screen = get_screen_for_region_index_offset(offset);
567 654492862 return get_scr(screen);
568 }
569
570 // The screen at (map, screen) must exist.
571 1439672793 mapscr* get_scr(int map, int screen)
572 {
573 1439672793 mapscr* scr = get_scr_maybe(map, screen);
574
1/2
✓ Branch 0 taken 1439672793 times.
✗ Branch 1 not taken.
1439672793 CHECK(scr);
575 1439672793 return scr;
576 }
577
578 837537064 mapscr* get_scr(int screen)
579 {
580 837537064 return get_scr(cur_map, screen);
581 }
582
583 // Returns null if active screen does not exist.
584 1615477546 mapscr* get_scr_maybe(int map, int screen)
585 {
586 DCHECK_RANGE_INCLUSIVE(screen, 0, 135);
587
588
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1615477546 times.
1615477546 if (map == cur_map)
589 {
590
2/2
✓ Branch 0 taken 1591344927 times.
✓ Branch 1 taken 24132619 times.
1615477546 if (screen == cur_screen)
591 1591344927 return origin_scr;
592
593 24132619 int index = screen*7;
594
2/2
✓ Branch 0 taken 21004836 times.
✓ Branch 1 taken 3127783 times.
24132619 if (temporary_screens[index])
595 21004836 return temporary_screens[index];
596
597
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3127783 times.
3127783 if (screen == home_screen)
598 return special_warp_return_scr;
599 3127783 }
600
601
4/6
✓ Branch 0 taken 11090 times.
✓ Branch 1 taken 3116693 times.
✓ Branch 2 taken 11090 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11090 times.
3127783 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
602 {
603 11090 int index = screen*7;
604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11090 times.
11090 if (FFCore.ScrollingScreensAll[index])
605 11090 return FFCore.ScrollingScreensAll[index];
606 }
607
608 3116693 return nullptr;
609 1615477546 }
610
611 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
612 7041653763 mapscr* get_scr_layer(int map, int screen, int layer)
613 {
614 DCHECK_LAYER_ZERO_INDEX(layer);
615
2/2
✓ Branch 0 taken 6442446955 times.
✓ Branch 1 taken 599206808 times.
7041653763 if (layer == 0)
616 599206808 return get_scr(map, screen);
617
618
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6442446955 times.
6442446955 if (map == cur_map)
619 {
620 6442446955 int index = screen*7 + layer;
621
2/2
✓ Branch 0 taken 6442378555 times.
✓ Branch 1 taken 68400 times.
6442446955 if (temporary_screens[index])
622 6442378555 return temporary_screens[index];
623
624
2/2
✓ Branch 0 taken 1860 times.
✓ Branch 1 taken 66540 times.
68400 if (screen == home_screen)
625 1860 return &special_warp_return_scrs[layer];
626 66540 }
627
628
1/2
✓ Branch 0 taken 66540 times.
✗ Branch 1 not taken.
66540 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
629 {
630 66540 int index = screen*7 + layer;
631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66540 times.
66540 if (FFCore.ScrollingScreensAll[index])
632 66540 return FFCore.ScrollingScreensAll[index];
633 }
634
635 NOTREACHED();
636 7041653763 }
637
638 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
639 6642507647 mapscr* get_scr_layer(int screen, int layer)
640 {
641 6642507647 return get_scr_layer(cur_map, screen, layer);
642 }
643
644 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
645 // Return nullptr if screen is not valid.
646 397072313 mapscr* get_scr_layer_valid(int screen, int layer)
647 {
648
2/2
✓ Branch 0 taken 82099893 times.
✓ Branch 1 taken 314972420 times.
397072313 if (mapscr* scr = get_scr_layer(cur_map, screen, layer); scr->is_valid())
649 82099893 return scr;
650 314972420 return nullptr;
651 397072313 }
652
653 401 mapscr* get_scr_current_region_dir(int screen, direction dir)
654 {
655 401 int x = get_region_relative_dx(screen);
656 401 int y = get_region_relative_dy(screen);
657
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
401 if (dir == left && x == 0)
658 71 return nullptr;
659
3/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
330 if (dir == right && x == 15)
660 return nullptr;
661
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
330 if (dir == down && y == 7)
662 return nullptr;
663
3/4
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 141 times.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
330 if (dir == up && y == 0)
664 189 return nullptr;
665
666 141 screen = screen_index_direction(screen, dir);
667
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (is_in_current_region(screen))
668 return get_scr(screen);
669
670 141 return nullptr;
671 401 }
672
673 183837 ffc_handle_t get_ffc_handle(ffc_id_t id)
674 {
675 183837 uint8_t screen = get_screen_for_region_index_offset(id / MAXFFCS);
676 183837 uint8_t i = id % MAXFFCS;
677 183837 mapscr* scr = get_scr(screen);
678 183837 ffcdata* ffc = &scr->getFFC(id % MAXFFCS);
679 183837 return {scr, screen, id, i, ffc};
680 }
681
682 34566 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen, int x, int y)
683 {
684 34566 x += get_region_relative_dx(screen) * 256;
685 34566 y += get_region_relative_dy(screen) * 176;
686 34566 return {x, y};
687 }
688
689 1049500 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen)
690 {
691 1049500 int x = get_region_relative_dx(screen) * 256;
692 1049500 int y = get_region_relative_dy(screen) * 176;
693 1049500 return {x, y};
694 }
695
696 12234601348 int32_t COMBOPOS(int32_t x, int32_t y)
697 {
698 DCHECK(x >= 0 && x < 256 && y >= 0 && y < 176);
699 12234601348 return (y & 0xF0) + (x >> 4);
700 }
701 int32_t COMBOPOS_B(int32_t x, int32_t y)
702 {
703 if(unsigned(x) >= 256 || unsigned(y) >= 176)
704 return -1;
705 return (y & 0xF0) + (x >> 4);
706 }
707 3466540185 int32_t COMBOX(int32_t pos)
708 {
709 3466540185 return pos % 16 * 16;
710 }
711 3466540185 int32_t COMBOY(int32_t pos)
712 {
713 3466540185 return pos & 0xF0;
714 }
715
716 112602921 rpos_t COMBOPOS_REGION(int32_t x, int32_t y)
717 {
718
2/2
✓ Branch 0 taken 84070201 times.
✓ Branch 1 taken 28532720 times.
112602921 if (!is_in_scrolling_region())
719 84070201 return (rpos_t) COMBOPOS(x, y);
720
721 DCHECK(is_in_world_bounds(x, y));
722 28532720 int scr_dx = x / (16*16);
723 28532720 int scr_dy = y / (11*16);
724 28532720 int pos = COMBOPOS(x%256, y%176);
725 28532720 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
726 112602921 }
727 6431441280 rpos_t COMBOPOS_REGION_B(int32_t x, int32_t y)
728 {
729
2/2
✓ Branch 0 taken 1400932 times.
✓ Branch 1 taken 6430040348 times.
6431441280 if (!is_in_world_bounds(x, y))
730 1400932 return rpos_t::None;
731
732 6430040348 int scr_dx = x / (16*16);
733 6430040348 int scr_dy = y / (11*16);
734 6430040348 int pos = COMBOPOS(x%256, y%176);
735 6430040348 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
736 6431441280 }
737 26534966 std::pair<int32_t, int32_t> COMBOXY_REGION(rpos_t rpos)
738 {
739 26534966 int scr_index = static_cast<int32_t>(rpos) / 176;
740 26534966 int scr_dx = scr_index % cur_region.screen_width;
741 26534966 int scr_dy = scr_index / cur_region.screen_width;
742 26534966 int pos = RPOS_TO_POS(rpos);
743 26534966 int x = scr_dx*16*16 + COMBOX(pos);
744 26534966 int y = scr_dy*11*16 + COMBOY(pos);
745 26534966 return {x, y};
746 }
747 60396 int32_t COMBOX_REGION(rpos_t rpos)
748 {
749 60396 auto [x, y] = COMBOXY_REGION(rpos);
750 60396 return x;
751 }
752 12225 int32_t COMBOY_REGION(rpos_t rpos)
753 {
754 12225 auto [x, y] = COMBOXY_REGION(rpos);
755 12225 return y;
756 }
757
758 70177 rpos_t COMBOPOS_REGION_INDEX(int32_t x, int32_t y)
759 {
760 DCHECK(is_in_world_bounds(x, y));
761
1/2
✓ Branch 0 taken 70177 times.
✗ Branch 1 not taken.
70177 if (!is_in_scrolling_region())
762 70177 return (rpos_t)(x + y * 16);
763
764 int scr_dx = x / 16;
765 int scr_dy = y / 11;
766 x %= 16;
767 y %= 11;
768 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + x + y * 16);
769 70177 }
770 70632 std::pair<int32_t, int32_t> COMBOXY_REGION_INDEX(rpos_t rpos)
771 {
772 70632 int scr_index = static_cast<int32_t>(rpos) / 176;
773 70632 int scr_dx = scr_index % cur_region.screen_width;
774 70632 int scr_dy = scr_index / cur_region.screen_width;
775 70632 int pos = RPOS_TO_POS(rpos);
776 70632 int x = scr_dx*16 + pos%16;
777 70632 int y = scr_dy*11 + pos/16;
778 70632 return {x, y};
779 }
780
781 88503108 int32_t mapind(int32_t map, int32_t scr)
782 {
783 88503108 return map * MAPSCRSNORMAL + scr;
784 }
785
786 FONT *get_zc_font(int index);
787
788 extern sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations;
789 extern movingblock mblock2; //mblock[4]?
790 extern portal mirror_portal;
791
792 void Z_message_d(const char *format,...)
793 {
794 #ifdef _DEBUG
795 char buf[512];
796 va_list ap;
797 va_start(ap, format);
798 vsprintf(buf, format, ap);
799 va_end(ap);
800
801 al_trace("%s",buf);
802 #else
803 format=format;
804 #endif
805 }
806
807
808
809 bool checktrigger=false;
810
811 void debugging_box(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
812 {
813 //reference/optimization: the start of the unused drawing command index can now be queried. -Gleeok
814 int32_t index = script_drawing_commands.GetNext();
815
816 if(index < 0)
817 return;
818
819 int32_t *sdci = &script_drawing_commands[index][0];
820
821 sdci[0] = RECTR;
822 sdci[1] = 30000;
823 sdci[2] = x1*10000;
824 sdci[3] = y1*10000;
825 sdci[4] = x2*10000;
826 sdci[5] = y2*10000;
827 sdci[6] = 10000;
828 sdci[7] = 10000;
829 sdci[8] = 0;
830 sdci[9] = 0;
831 sdci[10] = 0;
832 sdci[11] = 10000;
833 sdci[12] = 1280000;
834 }
835
836 void clear_dmap(word i)
837 {
838 DMaps[i].clear();
839 }
840
841 void clear_dmaps()
842 {
843 for(int32_t i=0; i<MAXDMAPS; i++)
844 {
845 clear_dmap(i);
846 }
847 }
848
849 223615827 int32_t isdungeon(int32_t dmap, int32_t screen)
850 {
851
2/2
✓ Branch 0 taken 223570147 times.
✓ Branch 1 taken 45680 times.
223615827 if (dmap < 0) dmap = cur_dmap;
852
853 // dungeons can have any dlevel above 0
854
2/2
✓ Branch 0 taken 122366382 times.
✓ Branch 1 taken 101249445 times.
223615827 if((DMaps[dmap].type&dmfTYPE) == dmDNGN)
855 {
856
2/2
✓ Branch 0 taken 9961 times.
✓ Branch 1 taken 101239484 times.
101249445 if (get_canonical_scr(cur_map, screen)->flags6&fCAVEROOM)
857 9961 return 0;
858
859 101239484 return 1;
860 }
861
862 // dlevels that aren't dungeons are caves
863
2/2
✓ Branch 0 taken 36827 times.
✓ Branch 1 taken 122329555 times.
122366382 if (get_canonical_scr(cur_map, screen)->flags6&fDUNGEONROOM)
864 36827 return 1;
865
866 122329555 return 0;
867 223615827 }
868
869 39942476 int32_t isdungeon(int32_t screen)
870 {
871 39942476 return isdungeon(cur_dmap, screen);
872 }
873
874 183546414 int32_t isdungeon()
875 {
876 183546414 return isdungeon(cur_dmap, Hero.current_screen);
877 }
878
879 88932 bool canPermSecret(int32_t dmap, int32_t screen)
880 {
881
2/2
✓ Branch 0 taken 13910 times.
✓ Branch 1 taken 75022 times.
88932 return (!isdungeon(dmap, screen) || get_qr(qr_DUNGEON_DMAPS_PERM_SECRETS));
882 }
883
884 1358576938 int32_t MAPCOMBO(int32_t x, int32_t y)
885 {
886 1358576938 x = vbound(x, 0, world_w-1);
887 1358576938 y = vbound(y, 0, world_h-1);
888 1358576938 int pos = COMBOPOS(x%256, y%176);
889 1358576938 mapscr* scr = get_scr_for_world_xy(x, y);
890 1358576938 return scr->data[pos];
891 }
892
893 //specific layers 1 to 6
894 1709728262 int32_t MAPCOMBOL(int32_t layer,int32_t x,int32_t y)
895 {
896 DCHECK(layer >= 1 && layer <= 6);
897
3/4
✓ Branch 0 taken 1689370280 times.
✓ Branch 1 taken 20357982 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1689370280 times.
1709728262 if (!is_in_world_bounds(x, y) || layer <= 0)
898 20357982 return 0;
899
900 1689370280 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
901
2/2
✓ Branch 0 taken 505922516 times.
✓ Branch 1 taken 1183447764 times.
1689370280 if (!m->is_valid())
902 1183447764 return 0;
903
904 505922516 int pos = COMBOPOS(x%256, y%176);
905 505922516 return m->data[pos];
906 1709728262 }
907
908 int32_t MAPCSETL(int32_t layer,int32_t x,int32_t y)
909 {
910 DCHECK(layer >= 1 && layer <= 6);
911 if (!is_in_world_bounds(x, y) || layer <= 0)
912 return 0;
913
914 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
915 if (!m->is_valid())
916 return 0;
917
918 int pos = COMBOPOS(x%256, y%176);
919 return m->cset[pos];
920 }
921
922 189308 int32_t MAPFLAGL(int32_t layer,int32_t x,int32_t y)
923 {
924 DCHECK(layer >= 1 && layer <= 6);
925
2/4
✓ Branch 0 taken 189308 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189308 times.
189308 if (!is_in_world_bounds(x, y) || layer <= 0)
926 return 0;
927
928 189308 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
929
2/2
✓ Branch 0 taken 163782 times.
✓ Branch 1 taken 25526 times.
189308 if (!m->is_valid())
930 25526 return 0;
931
932 163782 int pos = COMBOPOS(x%256, y%176);
933 163782 return m->sflag[pos];
934 189308 }
935
936 6281 int32_t COMBOTYPEL(int32_t layer,int32_t x,int32_t y)
937 {
938 DCHECK(layer >= 1 && layer <= 6);
939
2/4
✓ Branch 0 taken 6281 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6281 times.
6281 if (!is_in_world_bounds(x, y) || layer <= 0)
940 return 0;
941
942 6281 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
943
2/2
✓ Branch 0 taken 5926 times.
✓ Branch 1 taken 355 times.
6281 if (!m->is_valid())
944 355 return 0;
945
946 5926 int pos = COMBOPOS(x%256, y%176);
947 5926 return combobuf[m->data[pos]].type;
948 6281 }
949
950 189308 int32_t MAPCOMBOFLAGL(int32_t layer,int32_t x,int32_t y)
951 {
952 DCHECK(layer >= 1 && layer <= 6);
953
2/4
✓ Branch 0 taken 189308 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189308 times.
189308 if (!is_in_world_bounds(x, y) || layer <= 0)
954 return 0;
955
956 189308 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
957
2/2
✓ Branch 0 taken 163782 times.
✓ Branch 1 taken 25526 times.
189308 if (!m->is_valid())
958 25526 return 0;
959
960 163782 int pos = COMBOPOS(x%256, y%176);
961 163782 return combobuf[m->data[pos]].flag;
962 189308 }
963
964
965 // True if the FFC covers x, y and is not ethereal or a changer.
966 2467221699 bool ffcIsAt(const ffc_handle_t& ffc_handle, int32_t x, int32_t y)
967 {
968
2/2
✓ Branch 0 taken 746713622 times.
✓ Branch 1 taken 1720508077 times.
2467221699 if (ffc_handle.data()<=0)
969 746713622 return false;
970
971
2/2
✓ Branch 0 taken 300858479 times.
✓ Branch 1 taken 1419649598 times.
1720508077 if((ffc_handle.ffc->flags&(ffc_changer|ffc_ethereal))!=0)
972 300858479 return false;
973
974 1419649598 int32_t fx=ffc_handle.ffc->x.getInt();
975
4/4
✓ Branch 0 taken 976103902 times.
✓ Branch 1 taken 443545696 times.
✓ Branch 2 taken 866092281 times.
✓ Branch 3 taken 110011621 times.
1419649598 if(x<fx || x>fx+(ffc_handle.scr->ffEffectWidth(ffc_handle.i)-1)) // FFC sizes are weird.
976 1309637977 return false;
977
978 110011621 int32_t fy=ffc_handle.ffc->y.getInt();
979
4/4
✓ Branch 0 taken 80030220 times.
✓ Branch 1 taken 29981401 times.
✓ Branch 2 taken 60063858 times.
✓ Branch 3 taken 19966362 times.
110011621 if(y<fy || y>fy+(ffc_handle.scr->ffEffectHeight(ffc_handle.i)-1))
980 90045259 return false;
981
982 19966362 return true;
983 2467221699 }
984
985 995832518 int32_t MAPFFCOMBO(int32_t x,int32_t y)
986 {
987
2/2
✓ Branch 0 taken 12960971 times.
✓ Branch 1 taken 982871547 times.
995832518 if (auto ffc_handle = getFFCAt(x, y))
988 12960971 return ffc_handle->data();
989 982871547 return 0;
990 995832518 }
991
992 207232 int32_t MAPCSET(int32_t x, int32_t y)
993 {
994
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 207232 times.
207232 if (!is_in_world_bounds(x, y))
995 return 0;
996 207232 mapscr* scr = get_scr_for_world_xy(x, y);
997 207232 int pos = COMBOPOS(x%256, y%176);
998 207232 return scr->cset[pos];
999 207232 }
1000
1001 73661746 int32_t MAPFLAG(int32_t x, int32_t y)
1002 {
1003
2/2
✓ Branch 0 taken 28140 times.
✓ Branch 1 taken 73633606 times.
73661746 if (!is_in_world_bounds(x, y))
1004 28140 return 0;
1005 73633606 mapscr* scr = get_scr_for_world_xy(x, y);
1006 73633606 int pos = COMBOPOS(x%256, y%176);
1007 73633606 return scr->sflag[pos];
1008 73661746 }
1009
1010 147476446 int32_t COMBOTYPE(int32_t x,int32_t y)
1011 {
1012 147476446 int32_t b=1;
1013
2/2
✓ Branch 0 taken 87069785 times.
✓ Branch 1 taken 60406661 times.
147476446 if(x&8) b<<=2;
1014
2/2
✓ Branch 0 taken 75307620 times.
✓ Branch 1 taken 72168826 times.
147476446 if(y&8) b<<=1;
1015
1016
2/2
✓ Branch 0 taken 294945854 times.
✓ Branch 1 taken 147469147 times.
442415001 for (int32_t i = 0; i <= 1; ++i)
1017 {
1018
2/2
✓ Branch 0 taken 284612906 times.
✓ Branch 1 taken 10332948 times.
294945854 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1019 {
1020
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 284612906 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
284612906 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x, y, i)) return cNONE;
1021 284612906 }
1022 else
1023 {
1024
4/4
✓ Branch 0 taken 10451 times.
✓ Branch 1 taken 10322497 times.
✓ Branch 2 taken 3152 times.
✓ Branch 3 taken 7299 times.
10332948 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x, y, i)) return cNONE;
1025 }
1026 294938555 }
1027
1028 147469147 newcombo const& cmb = combobuf[MAPCOMBO(x,y)];
1029
5/6
✓ Branch 0 taken 3545559 times.
✓ Branch 1 taken 143923588 times.
✓ Branch 2 taken 2988025 times.
✓ Branch 3 taken 557534 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2988025 times.
147469147 if (cmb.type == cWATER && (cmb.walk&b) && ((cmb.walk>>4)&b))
1030 {
1031
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2988025 times.
2988025 if(cmb.usrflags&cflag4) return cSHALLOWWATER;
1032
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2988025 times.
2988025 if(cmb.usrflags&cflag3) return cNONE;
1033 2988025 }
1034 147469147 return cmb.type;
1035 147476446 }
1036
1037 50124257 int32_t FFCOMBOTYPE(int32_t x,int32_t y)
1038 {
1039 50124257 return combobuf[MAPFFCOMBO(x,y)].type;
1040 }
1041
1042 4954844 int32_t FFORCOMBO(int32_t x, int32_t y)
1043 {
1044
2/2
✓ Branch 0 taken 58516 times.
✓ Branch 1 taken 4896328 times.
4954844 if (auto ffc_handle = getFFCAt(x, y))
1045 58516 return ffc_handle->data();
1046
1047 4896328 return MAPCOMBO(x,y);
1048 4954844 }
1049
1050 int32_t FFORCOMBOTYPE(int32_t x, int32_t y)
1051 {
1052 for (int32_t i = 0; i <= 1; ++i)
1053 {
1054 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1055 {
1056 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1057 }
1058 else
1059 {
1060 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1061 }
1062 }
1063 int32_t b=1;
1064
1065 if(x&8) b<<=2;
1066
1067 if(y&8) b<<=1;
1068 newcombo const& cmb = combobuf[FFORCOMBO(x,y)];
1069 if (cmb.type == cWATER && (cmb.usrflags&cflag4) && (cmb.walk&b)) return cSHALLOWWATER;
1070 if (cmb.type == cWATER && (cmb.usrflags&cflag3) && (cmb.walk&b)) return cNONE;
1071 return cmb.type;
1072 }
1073
1074 int32_t FFORCOMBO_L(int32_t layer, int32_t x, int32_t y)
1075 {
1076 if (auto ffc_handle = getFFCAt(x, y))
1077 return ffc_handle->data();
1078
1079 return layer ? MAPCOMBOL(layer, x, y) : MAPCOMBO(x,y);
1080 }
1081
1082 int32_t FFORCOMBOTYPE_L(int32_t layer, int32_t x, int32_t y)
1083 {
1084 return combobuf[FFORCOMBO_L(layer,x,y)].type;
1085 }
1086
1087 70144758 int32_t MAPCOMBOFLAG(int32_t x,int32_t y)
1088 {
1089
2/2
✓ Branch 0 taken 27852 times.
✓ Branch 1 taken 70116906 times.
70144758 if (!is_in_world_bounds(x, y))
1090 27852 return 0;
1091
1092 70116906 mapscr* scr = get_scr_for_world_xy(x, y);
1093 70116906 int pos = COMBOPOS(x%256, y%176);
1094 70116906 return combobuf[scr->data[pos]].flag;
1095 70144758 }
1096
1097 56841587 int32_t MAPFFCOMBOFLAG(int32_t x,int32_t y)
1098 {
1099
2/2
✓ Branch 0 taken 746177 times.
✓ Branch 1 taken 56095410 times.
56841587 if (auto ffc_handle = getFFCAt(x, y))
1100 746177 return ffc_handle->cflag();
1101
1102 56095410 return 0;
1103 56841587 }
1104
1105 1312954948 std::optional<ffc_handle_t> getFFCAt(int32_t x, int32_t y)
1106 {
1107 2788505471 return find_ffc([&](const ffc_handle_t& ffc_handle) {
1108 1475550523 return ffcIsAt(ffc_handle, x, y);
1109 });
1110 }
1111
1112 3044 int32_t MAPCOMBO(const rpos_handle_t& rpos_handle)
1113 {
1114
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3044 times.
3044 if (!rpos_handle.scr->is_valid()) return 0;
1115 3044 return rpos_handle.data();
1116 3044 }
1117
1118 3127450637 int32_t MAPCOMBO2(int32_t layer, int32_t x, int32_t y)
1119 {
1120 DCHECK_LAYER_NEG1_INDEX(layer);
1121
2/2
✓ Branch 0 taken 22360558 times.
✓ Branch 1 taken 3105090079 times.
3127450637 if (!is_in_world_bounds(x, y)) return 0;
1122
2/2
✓ Branch 0 taken 3033492992 times.
✓ Branch 1 taken 71597087 times.
3105090079 if (layer == -1) return MAPCOMBO(x, y);
1123
1124 3033492992 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1125
2/2
✓ Branch 0 taken 2055282097 times.
✓ Branch 1 taken 978210895 times.
3033492992 if (!rpos_handle.scr->is_valid()) return 0;
1126
1127 978210895 return rpos_handle.data();
1128 3127450637 }
1129
1130 17563007 static void _handle_screen_load_trigger(const combined_handle_t& handle)
1131 {
1132 17563007 auto cid = handle.data();
1133 17563007 auto* cmb = &handle.combo();
1134 17563007 bool done = false;
1135 17563007 std::set<int32_t> visited;
1136
2/2
✓ Branch 0 taken 17563007 times.
✓ Branch 1 taken 17563007 times.
35126014 while(!done)
1137 {
1138
2/4
✓ Branch 0 taken 17563007 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17563007 times.
17563007 if(visited.contains(cid))
1139 {
1140 Z_error("Combo '%d' was part of an infinite trigger loop, breaking out of loop", cid);
1141 break; // prevent infinite loop
1142 }
1143
1/2
✓ Branch 0 taken 17563007 times.
✗ Branch 1 not taken.
17563007 visited.insert(cid);
1144
1145 17563007 done = true; // don't loop again unless something changes
1146
1/2
✓ Branch 0 taken 17563007 times.
✗ Branch 1 not taken.
18439730 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
1147 876723 return trig.trigger_flags.get(TRIGFLAG_SCREENLOAD);
1148 });
1149
2/4
✓ Branch 0 taken 17563007 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17563007 times.
17563007 if(handle.data() != cid)
1150 {
1151 cid = handle.data();
1152 cmb = &handle.combo();
1153 done = false; // loop again for the new combo
1154 }
1155 }
1156 17563007 }
1157 51230 static void handle_screen_load_trigger(const screen_handles_t& screen_handles)
1158 {
1159 51230 for_every_combo_in_screen(screen_handles, _handle_screen_load_trigger);
1160 51230 }
1161 34820 void handle_region_load_trigger()
1162 {
1163
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 34668 times.
34820 if (is_in_scrolling_region())
1164 {
1165
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 19456 times.
19608 for (int screen = 0; screen < 128; screen++)
1166 {
1167
2/2
✓ Branch 0 taken 18156 times.
✓ Branch 1 taken 1300 times.
19456 if (is_in_current_region(screen))
1168 1300 handle_screen_load_trigger(create_screen_handles_one(get_scr(screen)));
1169 19456 }
1170 152 }
1171 34668 else handle_screen_load_trigger(create_screen_handles_one(get_scr(Hero.current_screen)));
1172 34820 }
1173
1174 15262 static void apply_state_changes_to_screen(mapscr& scr, int32_t map, int32_t screen, int32_t flags, bool secrets_do_replay_comment)
1175 {
1176 15262 auto screen_handles = create_screen_handles_one(&scr);
1177
1178
3/4
✓ Branch 0 taken 539 times.
✓ Branch 1 taken 14723 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 539 times.
15262 if ((flags & mSECRET) && canPermSecret(cur_dmap, screen))
1179 {
1180 539 reveal_hidden_stairs(&scr, screen, false);
1181 539 bool do_layers = false;
1182 539 bool from_active_screen = false;
1183 539 trigger_secrets_for_screen_internal(screen_handles, do_layers, from_active_screen, -3, secrets_do_replay_comment);
1184 539 }
1185
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if (flags & mLIGHTBEAM)
1186 {
1187 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
1188 if (rpos_handle.ctype() == cLIGHTTARGET)
1189 {
1190 if (!(rpos_handle.combo().usrflags&cflag1)) //Unlit version
1191 rpos_handle.increment_data();
1192 }
1193 });
1194 }
1195
1196 15262 int lvl = DMaps[cur_dmap].level;
1197 15262 toggle_switches(game->lvlswitches[lvl], true, screen_handles);
1198 15262 toggle_gswitches_load(screen_handles);
1199
1200
2/2
✓ Branch 0 taken 15170 times.
✓ Branch 1 taken 92 times.
15262 if(flags&mLOCKBLOCK) // if special stuff done before
1201 {
1202 92 remove_screenstatecombos2(screen_handles, false, cLOCKBLOCK, cLOCKBLOCK2);
1203 92 }
1204
1205
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mBOSSLOCKBLOCK) // if special stuff done before
1206 {
1207 remove_screenstatecombos2(screen_handles, false, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
1208 }
1209
1210
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mCHEST) // if special stuff done before
1211 {
1212 remove_screenstatecombos2(screen_handles, false, cCHEST, cCHEST2);
1213 }
1214
1215
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mCHEST) // if special stuff done before
1216 {
1217 remove_screenstatecombos2(screen_handles, false, cLOCKEDCHEST, cLOCKEDCHEST2);
1218 }
1219
1220
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mBOSSCHEST) // if special stuff done before
1221 {
1222 remove_screenstatecombos2(screen_handles, false, cBOSSCHEST, cBOSSCHEST2);
1223 }
1224
1225
1226 15262 int mi = mapind(map, screen);
1227 15262 clear_xdoors_mi(screen_handles, mi);
1228 15262 clear_xstatecombos_mi(screen_handles, mi);
1229
1230 15262 handle_screen_load_trigger(screen_handles);
1231 15262 }
1232
1233 53194 std::optional<mapscr> load_temp_mapscr_and_apply_secrets(int32_t map, int32_t screen, int32_t layer, bool secrets, bool secrets_do_replay_comment)
1234 {
1235
2/4
✓ Branch 0 taken 53194 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53194 times.
53194 if (map < 0 || screen < 0)
1236 return std::nullopt;
1237
1238 53194 const mapscr* source = get_canonical_scr(map, screen);
1239
2/2
✓ Branch 0 taken 39256 times.
✓ Branch 1 taken 13938 times.
53194 if (!source->is_valid())
1240 13938 return std::nullopt;
1241
1242
2/2
✓ Branch 0 taken 7936 times.
✓ Branch 1 taken 31320 times.
39256 if (layer >= 0)
1243 {
1244
2/2
✓ Branch 0 taken 23994 times.
✓ Branch 1 taken 7326 times.
31320 if (source->layermap[layer] <= 0)
1245 23994 return std::nullopt;
1246
1247 7326 source = get_canonical_scr(source->layermap[layer] - 1, source->layerscreen[layer]);
1248
1/2
✓ Branch 0 taken 7326 times.
✗ Branch 1 not taken.
7326 if (!source->is_valid())
1249 return std::nullopt;
1250 7326 }
1251
1252
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 int flags = secrets ? game->maps[mapind(map, screen)] : 0;
1253 15262 mapscr scr = *source;
1254
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 apply_state_changes_to_screen(scr, map, screen, flags, secrets_do_replay_comment);
1255
1256
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 return scr;
1257 53194 }
1258
1259 27203 static int32_t MAPCOMBO3_impl(int32_t map, int32_t screen, int32_t layer, int32_t pos, bool secrets)
1260 {
1261
2/4
✓ Branch 0 taken 27203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27203 times.
27203 if (map < 0 || screen < 0) return 0;
1262
1263
2/4
✓ Branch 0 taken 27203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27203 times.
27203 if(pos>175 || pos < 0)
1264 return 0;
1265
1266 // TODO: consider caching this (invalidate on any modification via scripting, or anything
1267 // `apply_state_changes_to_screen` checks).
1268
4/5
✓ Branch 0 taken 4736 times.
✓ Branch 1 taken 22467 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4736 times.
✓ Branch 4 taken 22467 times.
31939 if (auto s = load_temp_mapscr_and_apply_secrets(map, screen, layer, secrets))
1269 4736 return s->data[pos];
1270
1271 22467 return 0;
1272 27203 }
1273
1274 // Read from the current temporary screens or, if (map, screen) is not loaded,
1275 // load that screen and apply the relevant secrets before evaluating the combo at that position.
1276 137734926 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets)
1277 {
1278 DCHECK_LAYER_NEG1_INDEX(layer);
1279 DCHECK(map >= 0 && screen >= 0);
1280
1281
2/2
✓ Branch 0 taken 137707723 times.
✓ Branch 1 taken 27203 times.
137734926 if (is_in_current_region(map, screen)) return MAPCOMBO2(layer, x, y);
1282
1283 // Screen is not in the current region, so we have to load and trigger some secrets.
1284 27203 int pos = COMBOPOS(x, y);
1285 27203 return MAPCOMBO3_impl(map, screen, layer, pos, secrets);
1286 137734926 }
1287
1288 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, rpos_t rpos, bool secrets)
1289 {
1290 DCHECK_LAYER_NEG1_INDEX(layer);
1291 DCHECK(map >= 0 && screen >= 0);
1292 DCHECK(is_valid_rpos(rpos));
1293
1294 if (is_in_current_region(map, screen)) return MAPCOMBO(get_rpos_handle(rpos, layer + 1));
1295
1296 // Screen is not currently loaded, so we have to load and trigger some secrets.
1297 return MAPCOMBO3_impl(map, screen, layer, RPOS_TO_POS(rpos), secrets);
1298 }
1299
1300 int32_t MAPCSET2(int32_t layer,int32_t x,int32_t y)
1301 {
1302 DCHECK_LAYER_NEG1_INDEX(layer);
1303 if (!is_in_world_bounds(x, y))
1304 return 0;
1305 if (layer == -1) return MAPCSET(x, y);
1306
1307 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1308 if (!rpos_handle.scr->is_valid()) return 0;
1309
1310 return rpos_handle.cset();
1311 }
1312
1313 98920838 int32_t MAPFLAG2(int32_t layer,int32_t x,int32_t y)
1314 {
1315 DCHECK_LAYER_NEG1_INDEX(layer);
1316
3/4
✓ Branch 0 taken 1894252 times.
✓ Branch 1 taken 97026586 times.
✓ Branch 2 taken 1894252 times.
✗ Branch 3 not taken.
98920838 if (!get_qr(qr_BUGGED_LAYERED_FLAGS) && (!is_in_world_bounds(x, y)))
1317 return 0;
1318
2/2
✓ Branch 0 taken 81313609 times.
✓ Branch 1 taken 17607229 times.
98920838 if (layer == -1) return MAPFLAG(x, y);
1319
1320 81313609 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1321
2/2
✓ Branch 0 taken 62659027 times.
✓ Branch 1 taken 18654582 times.
81313609 if (!rpos_handle.scr->is_valid()) return 0;
1322
1323 18654582 return rpos_handle.sflag();
1324 98920838 }
1325
1326 int32_t COMBOTYPE2(int32_t layer,int32_t x,int32_t y)
1327 {
1328 if(layer < 1)
1329 {
1330 for (int32_t i = layer+1; i <= 1; ++i)
1331 {
1332 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1333 {
1334 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1335 }
1336 else
1337 {
1338 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1339 }
1340 }
1341 }
1342 if(layer==-1) return COMBOTYPE(x,y);
1343
1344 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1345 if (!rpos_handle.scr->is_valid()) return 0;
1346
1347 return rpos_handle.ctype();
1348 }
1349
1350 // Returns the flag for the combo at the given position.
1351 // This is also known as an "inherent flag".
1352 97144066 int32_t MAPCOMBOFLAG2(int32_t layer,int32_t x,int32_t y)
1353 {
1354 DCHECK_LAYER_NEG1_INDEX(layer);
1355
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 97143778 times.
97144066 if (!is_in_world_bounds(x, y))
1356 288 return 0;
1357
2/2
✓ Branch 0 taken 81255022 times.
✓ Branch 1 taken 15888756 times.
97143778 if (layer == -1) return MAPCOMBOFLAG(x, y);
1358
1359 81255022 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1360
2/2
✓ Branch 0 taken 62677905 times.
✓ Branch 1 taken 18577117 times.
81255022 if (!rpos_handle.scr->is_valid()) return 0;
1361
1362 18577117 return rpos_handle.cflag();
1363 97144066 }
1364
1365 11626947 bool HASFLAG(int32_t flag, int32_t layer, rpos_t rpos)
1366 {
1367 DCHECK_LAYER_ZERO_INDEX(layer);
1368 11626947 auto rpos_handle = get_rpos_handle(rpos, layer);
1369
2/2
✓ Branch 0 taken 4456954 times.
✓ Branch 1 taken 7169993 times.
11626947 if (!rpos_handle.scr->is_valid()) return false;
1370
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 7165428 times.
7169993 if (rpos_handle.sflag() == flag) return true;
1371
2/2
✓ Branch 0 taken 37705 times.
✓ Branch 1 taken 7127723 times.
7165428 if (rpos_handle.cflag() == flag) return true;
1372 7127723 return false;
1373 11626947 }
1374
1375 1697077 bool HASFLAG_ANY(int32_t flag, rpos_t rpos)
1376 {
1377 DCHECK(is_valid_rpos(rpos));
1378
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1697077 times.
1697077 if (rpos > region_max_rpos) return false;
1379
1380
2/2
✓ Branch 0 taken 11626947 times.
✓ Branch 1 taken 1654807 times.
13281754 for(auto q = 0; q < 7; ++q)
1381 {
1382
2/2
✓ Branch 0 taken 42270 times.
✓ Branch 1 taken 11584677 times.
11626947 if(HASFLAG(flag, q, rpos))
1383 42270 return true;
1384 11584677 }
1385 1654807 return false;
1386 1697077 }
1387
1388 const char *screenstate_string[32] =
1389 {
1390 "Door Up", "Door Down", "Door Left", "Door Right", "Item", "Special Item", "Some Enemies Never Return",
1391 "Temporary No Return", "Lock Blocks", "Boss Lock Blocks", "Chests", "Locked Chests",
1392 "Boss Locked Chests", "Secrets", "Visited", "Light Beams",
1393 "All Enemies Don't Return", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1394 "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1395 };
1396
1397 34860 void eventlog_mapflags()
1398 {
1399 34860 std::ostringstream oss;
1400
1401 34860 int mi = mapind(cur_map, home_screen);
1402
1/2
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
34860 dword g = game->maps[mi];
1403
1404
2/4
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 34860 times.
✗ Branch 3 not taken.
34860 oss << fmt::format("Screen ({}, {:02X})", cur_map+1, home_screen);
1405
2/2
✓ Branch 0 taken 14514 times.
✓ Branch 1 taken 20346 times.
34860 if(g) // Main States
1406 {
1407 static const int order[] =
1408 {
1409 mSECRET, mITEM, mSPECIALITEM, mLOCKBLOCK, mBOSSLOCKBLOCK,
1410 mCHEST, mLOCKEDCHEST, mBOSSCHEST,
1411 mDOOR_UP, mDOOR_DOWN, mDOOR_LEFT, mDOOR_RIGHT,
1412 mNEVERRET, mTMPNORET, mLIGHTBEAM, mNO_ENEMIES_RETURN
1413 };
1414
1415
1/2
✓ Branch 0 taken 14514 times.
✗ Branch 1 not taken.
14514 oss << " [";
1416 14514 bool comma = false;
1417
2/2
✓ Branch 0 taken 14514 times.
✓ Branch 1 taken 232224 times.
246738 for(int fl : order)
1418 {
1419
2/2
✓ Branch 0 taken 8979 times.
✓ Branch 1 taken 223245 times.
232224 if(!(g&fl))
1420 223245 continue;
1421 8979 byte ind = byte(log2(double(fl)));
1422
2/2
✓ Branch 0 taken 1922 times.
✓ Branch 1 taken 7057 times.
8979 if(comma)
1423
1/2
✓ Branch 0 taken 1922 times.
✗ Branch 1 not taken.
1922 oss << ", ";
1424
1/2
✓ Branch 0 taken 8979 times.
✗ Branch 1 not taken.
8979 oss << screenstate_string[ind];
1425 8979 comma = true;
1426 }
1427
1/2
✓ Branch 0 taken 14514 times.
✗ Branch 1 not taken.
14514 oss << "]";
1428 14514 }
1429
3/4
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 34822 times.
34860 if(game->xstates[mi]) // ExStates
1430 {
1431
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 oss << " Ex[";
1432 38 bool comma = false;
1433
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 1216 times.
1254 for(byte fl = 0; fl < 32; ++fl)
1434 {
1435
3/4
✓ Branch 0 taken 1216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 1172 times.
1216 if(game->xstates[mi] & (1<<fl))
1436 {
1437
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 38 times.
44 if(comma)
1438
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 oss << ", ";
1439
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
44 oss << int(fl);
1440 44 comma = true;
1441 44 }
1442 1216 }
1443
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 oss << "]";
1444 38 }
1445 { // ExDoors
1446
2/2
✓ Branch 0 taken 34860 times.
✓ Branch 1 taken 139440 times.
174300 for(int q = 0; q < 4; ++q)
1447 {
1448 139440 bool comma = false;
1449
3/4
✓ Branch 0 taken 139440 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 139438 times.
✓ Branch 3 taken 2 times.
139440 if(auto v = game->xdoors[mi][q])
1450 {
1451
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(comma)
1452 oss << ",";
1453
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else oss << " ExDoor";
1454
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 oss << "[" << dirstr[q];
1455
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18 for(int fl = 0; fl < 8; ++fl)
1456
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
19 if(v & (1<<fl))
1457
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 oss << " " << int(fl);
1458
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 oss << "]";
1459 2 comma = true;
1460 2 }
1461 139440 }
1462 }
1463
2/4
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 34860 times.
34860 Z_eventlog("%s\n", oss.str().c_str());
1464 34860 }
1465
1466 // set specific flag
1467 5616 void setmapflag(mapscr* scr, uint32_t flag)
1468 {
1469
2/2
✓ Branch 0 taken 5603 times.
✓ Branch 1 taken 13 times.
5616 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1470 5616 int mi = mapind(cur_map, scr->screen);
1471 5616 setmapflag_mi(scr, mi, flag);
1472 5616 }
1473 57 void setmapflag_homescr(uint32_t flag)
1474 {
1475 57 int mi = mapind(cur_map, home_screen);
1476 57 setmapflag_mi(origin_scr, mi, flag);
1477 57 }
1478 2023 void setmapflag_mi(int32_t mi, uint32_t flag)
1479 {
1480 2023 byte cscr = mi&((1<<7)-1);
1481 2023 byte cmap = (mi>>7);
1482 2023 mapscr* scr = origin_scr;
1483
2/2
✓ Branch 0 taken 834 times.
✓ Branch 1 taken 1189 times.
2023 if (is_in_current_region(cmap, cscr))
1484 1189 scr = get_scr(cmap, cscr);
1485
1486 2023 setmapflag_mi(scr, mi, flag);
1487 2023 }
1488
1489 8478 static void log_state_change(int map, int screen, std::string action)
1490 {
1491
6/6
✓ Branch 0 taken 1913 times.
✓ Branch 1 taken 6565 times.
✓ Branch 2 taken 996 times.
✓ Branch 3 taken 917 times.
✓ Branch 4 taken 352 times.
✓ Branch 5 taken 644 times.
8478 if (is_in_current_region(map, screen) || (map == cur_map && screen == home_screen))
1492 6917 Z_eventlog("[Map %d, Screen %02X (current)] %s\n", map + 1, screen, action.c_str());
1493 else
1494 1561 Z_eventlog("[Map %d, Screen %02X] %s\n", map + 1, screen, action.c_str());
1495 8478 }
1496
1497 7696 void setmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag)
1498 {
1499 7696 byte cscr = mi&((1<<7)-1);
1500 7696 byte cmap = (mi>>7);
1501
1502 7696 double temp=log2((double)flag);
1503
1/2
✓ Branch 0 taken 7696 times.
✗ Branch 1 not taken.
7696 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1504 7696 const char* replay_state_string = state_string;
1505
2/2
✓ Branch 0 taken 7176 times.
✓ Branch 1 taken 520 times.
7696 if(temp == 6) replay_state_string = "No Return";
1506
1507
3/4
✓ Branch 0 taken 7696 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1552 times.
✓ Branch 3 taken 6144 times.
7696 if (replay_is_active() && !(game->maps[mi] & flag))
1508
1/2
✓ Branch 0 taken 6144 times.
✗ Branch 1 not taken.
6144 replay_step_comment(fmt::format("map {} scr {} flag {}", cmap, cscr, replay_state_string));
1509 7696 game->maps[mi] |= flag;
1510
1/2
✓ Branch 0 taken 7696 times.
✗ Branch 1 not taken.
7696 log_state_change(cmap, cscr, fmt::format("State set: {}", state_string));
1511
1512
2/2
✓ Branch 0 taken 2507 times.
✓ Branch 1 taken 5189 times.
7696 if((scr->nocarry&flag)!=flag)
1513 {
1514 5189 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1515 5189 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1516
1517 5189 std::vector<int32_t> done;
1518
2/2
✓ Branch 0 taken 5094 times.
✓ Branch 1 taken 95 times.
5189 bool looped = (nmap==cmap+1 && nscr==cscr);
1519
1520
6/6
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 5147 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 364 times.
✓ Branch 4 taken 364 times.
✓ Branch 5 taken 5189 times.
5553 while((nmap!=0) && !looped && !(nscr>=128))
1521 {
1522
3/4
✓ Branch 0 taken 364 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 171 times.
✓ Branch 3 taken 193 times.
364 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1523 {
1524
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 log_state_change(nmap, nscr, "State change carried over");
1525
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 if (replay_is_active())
1526
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 replay_step_comment(fmt::format("map {} scr {} flag {} carry", nmap, nscr, replay_state_string));
1527
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 game->maps[((nmap-1)<<7)+nscr] |= flag;
1528 193 }
1529
1530 364 cmap=nmap;
1531 364 cscr=nscr;
1532 364 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1533 364 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1534
1535
2/2
✓ Branch 0 taken 889 times.
✓ Branch 1 taken 364 times.
1253 for(auto it = done.begin(); it != done.end(); it++)
1536 {
1537
2/2
✓ Branch 0 taken 847 times.
✓ Branch 1 taken 42 times.
889 if(*it == ((nmap-1)<<7)+nscr)
1538 42 looped = true;
1539 889 }
1540
1541
1/2
✓ Branch 0 taken 364 times.
✗ Branch 1 not taken.
364 done.push_back(((nmap-1)<<7)+nscr);
1542 }
1543 5189 }
1544 7696 }
1545
1546 void unsetmapflag_home(uint32_t flag, bool anyflag)
1547 {
1548 int mi = mapind(cur_map, home_screen);
1549 unsetmapflag_mi(origin_scr, mi, flag, anyflag);
1550 }
1551
1552 void unsetmapflag(mapscr* scr, uint32_t flag, bool anyflag)
1553 {
1554 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1555 int mi = mapind(cur_map, scr->screen);
1556 unsetmapflag_mi(scr, mi, flag, anyflag);
1557 }
1558
1559 471 void unsetmapflag_mi(int32_t mi, uint32_t flag, bool anyflag)
1560 {
1561 471 byte cscr = mi&((1<<7)-1);
1562 471 byte cmap = (mi>>7);
1563 471 mapscr* scr = origin_scr;
1564
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if (is_in_current_region(cmap, cscr))
1565 11 scr = get_scr(cmap, cscr);
1566
1567 471 unsetmapflag_mi(scr, mi, flag, anyflag);
1568 471 }
1569
1570 471 void unsetmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag, bool anyflag)
1571 {
1572 471 byte cscr = mi&((1<<7)-1);
1573 471 byte cmap = (mi>>7);
1574
1575
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if(anyflag)
1576 460 game->maps[mi] &= ~flag;
1577
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 else if(flag==mITEM || flag==mSPECIALITEM)
1578 {
1579 if(!(scr->flags4&fNOITEMRESET))
1580 game->maps[mi] &= ~flag;
1581 }
1582 11 else game->maps[mi] &= ~flag;
1583
1584 471 double temp=log2((double)flag);
1585
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1586
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 log_state_change(cmap, cscr, fmt::format("State unset: {}", state_string));
1587
1588
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 471 times.
471 if((scr->nocarry&flag)!=flag)
1589 {
1590 471 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1591 471 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1592
1593 471 std::vector<int32_t> done;
1594
2/2
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 5 times.
471 bool looped = (nmap==cmap+1 && nscr==cscr);
1595
1596
6/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 465 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 471 times.
555 while((nmap!=0) && !looped && !(nscr>=128))
1597 {
1598
3/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 72 times.
84 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1599 {
1600
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 log_state_change(nmap, nscr, "State change carried over");
1601
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 game->maps[((nmap-1)<<7)+nscr] &= ~flag;
1602 72 }
1603
1604 84 cmap=nmap;
1605 84 cscr=nscr;
1606 84 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1607 84 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1608
1609
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 546 times.
630 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1610 {
1611
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 6 times.
546 if(*it == ((nmap-1)<<7)+nscr)
1612 6 looped = true;
1613 546 }
1614
1615
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 done.push_back(((nmap-1)<<7)+nscr);
1616 }
1617 471 }
1618 471 }
1619
1620 50173955 bool getmapflag(int32_t screen, uint32_t flag)
1621 {
1622
2/2
✓ Branch 0 taken 1345925 times.
✓ Branch 1 taken 48828030 times.
50173955 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1623 50173955 return (game->maps[mi] & flag) != 0;
1624 }
1625 6228619 bool getmapflag(mapscr* scr, uint32_t flag)
1626 {
1627 6228619 return getmapflag(scr->screen, flag);
1628 }
1629
1630 39 void setxmapflag(int32_t screen, uint32_t flag)
1631 {
1632
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1633 39 setxmapflag_mi(mi, flag);
1634 39 }
1635 41 void setxmapflag_mi(int32_t mi, uint32_t flag)
1636 {
1637
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if(game->xstates[mi] & flag) return;
1638 41 byte cscr = mi&((1<<7)-1);
1639 41 byte cmap = (mi>>7);
1640
1641 41 byte temp=(byte)log2((double)flag);
1642
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 log_state_change(cmap, cscr, fmt::format("ExtraState set: {}", temp));
1643
1644 41 game->xstates[mi] |= flag;
1645
1646 41 mapscr* scr = origin_scr;
1647
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if (is_in_current_region(cmap, cscr))
1648 41 scr = get_scr(cmap, cscr);
1649
1650
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 if((scr->exstate_carry&flag)==flag)
1651 {
1652 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1653 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1654
1655 std::vector<int32_t> done;
1656 bool looped = (nmap==cmap+1 && nscr==cscr);
1657
1658 while((nmap!=0) && !looped && !(nscr>=128))
1659 {
1660 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1661 {
1662 log_state_change(nmap, nscr, "ExState change carried over");
1663 if (replay_is_active())
1664 replay_step_comment(fmt::format("map {} scr {} exstate {} carry", nmap, nscr, temp));
1665 game->xstates[((nmap-1)<<7)+nscr] |= flag;
1666 }
1667
1668 cmap=nmap;
1669 cscr=nscr;
1670 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1671 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1672
1673 for(auto it = done.begin(); it != done.end(); it++)
1674 {
1675 if(*it == ((nmap-1)<<7)+nscr)
1676 looped = true;
1677 }
1678
1679 done.push_back(((nmap-1)<<7)+nscr);
1680 }
1681 }
1682 41 }
1683 2 void unsetxmapflag(int32_t screen, uint32_t flag)
1684 {
1685
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1686 2 unsetxmapflag_mi(mi, flag);
1687 2 }
1688 2 void unsetxmapflag_mi(int32_t mi, uint32_t flag)
1689 {
1690
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(!(game->xstates[mi] & flag)) return;
1691 1 byte cscr = mi&((1<<7)-1);
1692 1 byte cmap = (mi>>7);
1693 1 byte temp=(byte)log2((double)flag);
1694
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 log_state_change(cmap, cscr, fmt::format("ExtraState unset: {}", temp));
1695 1 game->xstates[mi] &= ~flag;
1696
1697 1 mapscr* scr = origin_scr;
1698
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (is_in_current_region(cmap, cscr))
1699 1 scr = get_scr(cmap, cscr);
1700
1701
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if((scr->exstate_carry&flag)==flag)
1702 {
1703 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1704 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1705
1706 std::vector<int32_t> done;
1707 bool looped = (nmap==cmap+1 && nscr==cscr);
1708
1709 while((nmap!=0) && !looped && !(nscr>=128))
1710 {
1711 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1712 {
1713 log_state_change(nmap, nscr, "ExState change carried over");
1714 game->xstates[((nmap-1)<<7)+nscr] &= ~flag;
1715 }
1716
1717 cmap=nmap;
1718 cscr=nscr;
1719 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1720 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1721
1722 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1723 {
1724 if(*it == ((nmap-1)<<7)+nscr)
1725 looped = true;
1726 }
1727
1728 done.push_back(((nmap-1)<<7)+nscr);
1729 }
1730 }
1731 2 }
1732 63 bool getxmapflag(int32_t screen, uint32_t flag)
1733 {
1734
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
63 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1735 63 return getxmapflag_mi(mi, flag);
1736 }
1737 471479053 bool getxmapflag_mi(int32_t mi, uint32_t flag)
1738 {
1739 471479053 return (game->xstates[mi] & flag) != 0;
1740 }
1741
1742 4 void setxdoor_mi(uint mi, uint dir, uint ind, bool state)
1743 {
1744
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 if(mi > game->xdoors.size() || dir > 3 || ind > 8)
1745 return;
1746
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(!(game->xdoors[mi][dir] & (1<<ind)) == !state)
1747 return;
1748
1749
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 SETFLAG(game->xdoors[mi][dir], 1<<ind, state);
1750
1751 4 int cscr = mi % MAPSCRSNORMAL;
1752 4 int cmap = mi / MAPSCRSNORMAL;
1753
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (state)
1754
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] set", dirstr[dir], ind));
1755 else
1756 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] unset", dirstr[dir], ind));
1757 4 }
1758 471478985 bool getxdoor_mi(uint mi, uint dir, uint ind)
1759 {
1760
3/6
✓ Branch 0 taken 471478985 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 471478985 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 471478985 times.
471478985 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1761 return false;
1762 471478985 return (game->xdoors[mi][dir] & (1<<ind));
1763 471478985 }
1764 9 bool getxdoor(int32_t screen, uint dir, uint ind)
1765 {
1766 9 int mi = mapind(cur_map, screen);
1767 9 return getxdoor_mi(mi,dir,ind);
1768 }
1769
1770 401 void set_doorstate_mi(uint mi, uint dir)
1771 {
1772
1/2
✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
401 if(dir >= 4)
1773 return;
1774 401 setmapflag_mi(mi, mDOOR_UP << dir);
1775
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if(auto di = nextscr_mi(mi, dir))
1776 400 setmapflag_mi(*di, mDOOR_UP << oppositeDir[dir]);
1777 401 }
1778 401 void set_doorstate(uint screen, uint dir)
1779 {
1780 401 int mi = mapind(cur_map, screen);
1781 401 set_doorstate_mi(mi, dir);
1782 401 }
1783
1784 2 void set_xdoorstate_mi(uint mi, uint dir, uint ind, bool state)
1785 {
1786
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1787 return;
1788 2 setxdoor_mi(mi, dir, ind, state);
1789
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(auto di = nextscr_mi(mi, dir))
1790 2 setxdoor_mi(*di, oppositeDir[dir], ind, state);
1791 2 }
1792
1793 2 void set_xdoorstate(int32_t screen,uint dir, uint ind, bool state)
1794 {
1795 2 int mi = mapind(cur_map, screen);
1796 2 set_xdoorstate_mi(mi, dir, ind, state);
1797 2 }
1798
1799 57 int32_t WARPCODE(int32_t dmap,int32_t screen,int32_t dw)
1800 // returns: -1 = not a warp screen
1801 // 0+ = warp screen code ( high byte=dmap, low byte=scr )
1802 {
1803 57 const mapscr *scr = get_canonical_scr(DMaps[dmap].map, screen);
1804
1805
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(scr->room!=rWARP)
1806 return -1;
1807
1808 57 int32_t ring=scr->catchall;
1809 57 int32_t size=QMisc.warp[ring].size;
1810
1811
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 if(size==0)
1812 return -2;
1813
1814 57 int32_t index=-1;
1815
1816
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 57 times.
346 for(int32_t i=0; i<size; i++)
1817
6/6
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 173 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 173 times.
✓ Branch 5 taken 57 times.
289 if(dmap==QMisc.warp[ring].dmap[i] && screen==
1818 346 (QMisc.warp[ring].scr[i] + DMaps[dmap].xoff))
1819 57 index=i;
1820
1821
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(index==-1)
1822 return -3;
1823
1824 57 index = (index+dw)%size;
1825 57 return (QMisc.warp[ring].dmap[index] << 8) + QMisc.warp[ring].scr[index];
1826 57 }
1827
1828 14779694 void update_combo_cycling()
1829 {
1830 14779694 auto& combo_cache = combo_caches::can_cycle;
1831
1832 static int32_t newdata[176];
1833 static int32_t newcset[176];
1834 static bool initialized=false;
1835
1836 // Just a simple bit of optimization
1837
2/2
✓ Branch 0 taken 14779383 times.
✓ Branch 1 taken 311 times.
14779694 if(!initialized)
1838 {
1839
2/2
✓ Branch 0 taken 54736 times.
✓ Branch 1 taken 311 times.
55047 for(int32_t i=0; i<176; i++)
1840 {
1841 54736 newdata[i]=-1;
1842 54736 newcset[i]=-1;
1843 54736 }
1844
1845 311 initialized=true;
1846 311 }
1847
1848 14779694 std::set<uint16_t> restartanim;
1849
1850
1/2
✓ Branch 0 taken 14779694 times.
✗ Branch 1 not taken.
29948756 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
1851 15169062 int screen = scr->screen;
1852 int32_t x;
1853
1854
2/2
✓ Branch 0 taken 2669754912 times.
✓ Branch 1 taken 15169062 times.
2684923974 for(int32_t i=0; i<176; i++)
1855 {
1856 2669754912 x=scr->data[i];
1857 2669754912 auto& mini_cmb = combo_cache.minis[x];
1858
2/2
✓ Branch 0 taken 3273932 times.
✓ Branch 1 taken 2666480980 times.
2669754912 if (!mini_cmb.can_cycle)
1859 2666480980 continue;
1860
1861 3273932 newcombo const& cmb = combobuf[x];
1862
1863 //time to restart
1864
4/4
✓ Branch 0 taken 902694 times.
✓ Branch 1 taken 2371238 times.
✓ Branch 2 taken 474434 times.
✓ Branch 3 taken 428260 times.
3273932 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1865 {
1866 428260 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1867
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428260 times.
428260 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1868 428260 newdata[i] = c;
1869
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428240 times.
428260 if(!(cmb.animflags & AF_CYCLENOCSET))
1870
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428240 times.
428240 newcset[i] = cycle_under ? scr->undercset : cmb.nextcset;
1871
1872
2/2
✓ Branch 0 taken 427216 times.
✓ Branch 1 taken 1044 times.
428260 if(combobuf[c].animflags & AF_CYCLE)
1873 {
1874 1044 restartanim.insert(c);
1875 1044 }
1876 428260 }
1877 3273932 }
1878
1879 15169062 int rpos_base = (int)POS_TO_RPOS(0, region_scr_x, region_scr_y);
1880
2/2
✓ Branch 0 taken 2669754912 times.
✓ Branch 1 taken 15169062 times.
2684923974 for(int32_t i=0; i<176; i++)
1881 {
1882
2/2
✓ Branch 0 taken 428260 times.
✓ Branch 1 taken 2669326652 times.
2669754912 if(newdata[i]==-1)
1883 2669326652 continue;
1884
1885 428260 rpos_t rpos = (rpos_t)(rpos_base + i);
1886 428260 rpos_handle_t rpos_handle = {scr, screen, 0, rpos, i};
1887 428260 screen_combo_modify_preroutine(rpos_handle);
1888 428260 scr->data[i]=newdata[i];
1889
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428240 times.
428260 if(newcset[i]>-1)
1890 428240 scr->cset[i]=newcset[i];
1891 428260 screen_combo_modify_postroutine(rpos_handle);
1892
1893 428260 newdata[i]=-1;
1894 428260 newcset[i]=-1;
1895 428260 }
1896
1897 15169062 word c = scr->numFFC();
1898
2/2
✓ Branch 0 taken 15169062 times.
✓ Branch 1 taken 453640163 times.
468809225 for(word i=0; i<c; i++)
1899 {
1900 453640163 ffcdata& ffc = scr->ffcs[i];
1901 453640163 auto& mini_cmb = combo_cache.minis[ffc.data];
1902
2/2
✓ Branch 0 taken 4173 times.
✓ Branch 1 taken 453635990 times.
453640163 if (!mini_cmb.can_cycle)
1903 453635990 continue;
1904
1905 4173 newcombo const& cmb = combobuf[ffc.data];
1906
1907 //time to restart
1908
4/4
✓ Branch 0 taken 611 times.
✓ Branch 1 taken 3562 times.
✓ Branch 2 taken 503 times.
✓ Branch 3 taken 108 times.
4173 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1909 {
1910 108 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1911
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1912 108 zc_ffc_set(ffc, c);
1913
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if(!(cmb.animflags & AF_CYCLENOCSET))
1914
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 ffc.cset = cycle_under ? scr->undercset : cmb.nextcset;
1915
1916
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 60 times.
108 if(combobuf[ffc.data].animflags & AF_CYCLE)
1917 {
1918 60 restartanim.insert(ffc.data);
1919 60 }
1920 108 }
1921 4173 }
1922
1923
2/2
✓ Branch 0 taken 8418399 times.
✓ Branch 1 taken 6750663 times.
15169062 if(get_qr(qr_CMBCYCLELAYERS))
1924 {
1925
2/2
✓ Branch 0 taken 40503978 times.
✓ Branch 1 taken 6750663 times.
47254641 for(int32_t j=1; j<=6; j++)
1926 {
1927 40503978 mapscr* layer_scr = get_scr_layer_valid(screen, j);
1928
2/2
✓ Branch 0 taken 11588882 times.
✓ Branch 1 taken 28915096 times.
40503978 if (!layer_scr)
1929 28915096 continue;
1930
1931
2/2
✓ Branch 0 taken 2039643232 times.
✓ Branch 1 taken 11588882 times.
2051232114 for(int32_t i=0; i<176; i++)
1932 {
1933 2039643232 x=layer_scr->data[i];
1934 2039643232 auto& mini_cmb = combo_cache.minis[x];
1935
2/2
✓ Branch 0 taken 2230074 times.
✓ Branch 1 taken 2037413158 times.
2039643232 if (!mini_cmb.can_cycle)
1936 2037413158 continue;
1937
1938 2230074 newcombo const& cmb = combobuf[x];
1939
1940 //time to restart
1941
4/4
✓ Branch 0 taken 48416 times.
✓ Branch 1 taken 2181658 times.
✓ Branch 2 taken 37483 times.
✓ Branch 3 taken 10933 times.
2230074 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1942 {
1943 10933 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1944
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10933 times.
10933 auto c = cycle_under ? layer_scr->undercombo : cmb.nextcombo;
1945 10933 newdata[i] = c;
1946
2/2
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 10864 times.
10933 if(!(cmb.animflags & AF_CYCLENOCSET))
1947
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10864 times.
10864 newcset[i] = cycle_under ? layer_scr->undercset : cmb.nextcset;
1948 69 else newcset[i] = layer_scr->cset[i];
1949
1950
2/2
✓ Branch 0 taken 950 times.
✓ Branch 1 taken 9983 times.
10933 if(combobuf[c].animflags & AF_CYCLE)
1951 {
1952 9983 restartanim.insert(c);
1953 9983 }
1954 10933 }
1955 2230074 }
1956
1957
2/2
✓ Branch 0 taken 2039643232 times.
✓ Branch 1 taken 11588882 times.
2051232114 for (int32_t i=0; i<176; i++)
1958 {
1959
2/2
✓ Branch 0 taken 2039632299 times.
✓ Branch 1 taken 10933 times.
2039643232 if(newdata[i]!=-1)
1960 {
1961 10933 layer_scr->data[i]=newdata[i];
1962
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10933 times.
10933 if(newcset[i]>-1)
1963 10933 layer_scr->cset[i]=newcset[i];
1964 10933 newdata[i]=-1;
1965 10933 newcset[i]=-1;
1966 10933 }
1967 2039643232 }
1968 11588882 }
1969 6750663 }
1970 15169062 });
1971
1972
2/2
✓ Branch 0 taken 14779694 times.
✓ Branch 1 taken 2661 times.
14782355 for (auto i : restartanim)
1973 {
1974 2661 combobuf[i].tile = combobuf[i].o_tile;
1975 2661 combobuf[i].cur_frame=0;
1976 2661 combobuf[i].aclk = 0;
1977
1/2
✓ Branch 0 taken 2661 times.
✗ Branch 1 not taken.
2661 combo_caches::drawing.refresh(i);
1978 }
1979 14779694 }
1980
1981 1212981589 bool iswater_type(int32_t type)
1982 {
1983 // return type==cOLD_WATER || type==cSWIMWARP || type==cDIVEWARP || type==cDIVEWARPB || type==cDIVEWARPC || type==cDIVEWARPD || type==cSWIMWARPB || type==cSWIMWARPC || type==cSWIMWARPD;
1984 1212981589 return (combo_class_buf[type].water!=0);
1985 }
1986
1987 bool iswater(int32_t combo)
1988 {
1989 return iswater_type(combobuf[combo].type) && !DRIEDLAKE;
1990 }
1991 1135408 int32_t iswaterexzq(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck)
1992 {
1993 1135408 return iswaterex(combo, map, screen, layer, x, y, secrets, fullcheck, LayerCheck);
1994 }
1995
1996 // (x, y) are world coordinates
1997 58744386 int32_t iswaterex_z3(int32_t combo, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
1998 {
1999
8/8
✓ Branch 0 taken 58698235 times.
✓ Branch 1 taken 46151 times.
✓ Branch 2 taken 58657903 times.
✓ Branch 3 taken 40332 times.
✓ Branch 4 taken 58591157 times.
✓ Branch 5 taken 66746 times.
✓ Branch 6 taken 59577 times.
✓ Branch 7 taken 58531580 times.
58744386 if (x<0 || x>=world_w || y<0 || y>=world_h)
2000 212806 return false;
2001
2002 58531580 return iswaterex(combo, cur_map, cur_screen, layer, x, y, secrets, fullcheck, LayerCheck, ShallowCheck, hero, out_handle);
2003 58744386 }
2004
2005 97204252 int32_t iswaterex(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
2006 {
2007 DCHECK_LAYER_NEG1_INDEX(layer);
2008 //Honestly, fullcheck is kinda useless... I made this function back when I thought it was checking the entire combo and not just a glorified x/y value.
2009 //Fullcheck makes no sense to ever be on, but hey I guess it's here in case you ever need it...
2010
2011 //Oh hey, Zoras might actually need it. Nevermind, this had a use!
2012
2/2
✓ Branch 0 taken 57354791 times.
✓ Branch 1 taken 39849461 times.
97204252 if (get_qr(qr_SMARTER_WATER))
2013 {
2014
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 57354791 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
57354791 if (DRIEDLAKE) return 0;
2015
5/6
✓ Branch 0 taken 19559904 times.
✓ Branch 1 taken 37794887 times.
✓ Branch 2 taken 6518562 times.
✓ Branch 3 taken 13041342 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6518562 times.
57354791 if (LayerCheck && (get_qr(qr_WATER_ON_LAYER_1) || get_qr(qr_WATER_ON_LAYER_2))) //LayerCheck is a bit dumber, but it lets me add this QR without having to replace all calls, again.
2016 {
2017
2/2
✓ Branch 0 taken 37777366 times.
✓ Branch 1 taken 12368012 times.
50145378 for (int32_t m = layer; m <= 1; m++)
2018 {
2019
5/6
✓ Branch 0 taken 24736024 times.
✓ Branch 1 taken 13041342 times.
✓ Branch 2 taken 12368012 times.
✓ Branch 3 taken 12368012 times.
✓ Branch 4 taken 12368012 times.
✗ Branch 5 not taken.
50145378 if (m < 0 || m == 0 && get_qr(qr_WATER_ON_LAYER_1)
2020
1/2
✓ Branch 0 taken 12368012 times.
✗ Branch 1 not taken.
24736024 || m == 1 && get_qr(qr_WATER_ON_LAYER_2))
2021 {
2022 37777366 int32_t checkwater = iswaterex(combo, map, screen, m, x, y, secrets, fullcheck, false, ShallowCheck);
2023
2/2
✓ Branch 0 taken 37104036 times.
✓ Branch 1 taken 673330 times.
37777366 if (checkwater > 0)
2024 {
2025
2/2
✓ Branch 0 taken 673272 times.
✓ Branch 1 taken 58 times.
673330 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, m+1);
2026 673330 return checkwater;
2027 }
2028 37104036 }
2029 37104036 }
2030 12368012 return 0;
2031 }
2032 else
2033 {
2034
2/2
✓ Branch 0 taken 44328122 times.
✓ Branch 1 taken 42139295 times.
86467417 for(int32_t i=(fullcheck?3:0); i>=0; i--)
2035 {
2036 44328122 int32_t tx2=((i&2)<<2)+x;
2037 44328122 int32_t ty2=((i&1)<<3)+y;
2038 44328122 int32_t b = i; //Originally b was not needed and I read off i, but then I added the boolean for fullcheck.
2039 //In which case it's just easier to change b if fullcheck is false instead of changing i and potentially screwing up the for loop.
2040
2/2
✓ Branch 0 taken 21673 times.
✓ Branch 1 taken 44306449 times.
44328122 if (!fullcheck)
2041 {
2042 44306449 tx2 = x;
2043 44306449 ty2 = y;
2044
2/2
✓ Branch 0 taken 24875581 times.
✓ Branch 1 taken 19430868 times.
44306449 if(tx2&8) b+=2;
2045
2/2
✓ Branch 0 taken 20524110 times.
✓ Branch 1 taken 23782339 times.
44306449 if(ty2&8) b+=1;
2046 44306449 }
2047
2/2
✓ Branch 0 taken 94774118 times.
✓ Branch 1 taken 43483889 times.
138258007 for (int32_t m = layer; m <= 1; m++)
2048 {
2049 94774118 newcombo const& cmb = combobuf[MAPCOMBO3(map, screen, m,tx2,ty2, true)];
2050
2/2
✓ Branch 0 taken 17735727 times.
✓ Branch 1 taken 77038391 times.
94774118 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2051 {
2052
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17735727 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17735727 if (cmb.type == cBRIDGE && !(cmb.walk&(1<<b)))
2053 {
2054 return 0;
2055 }
2056 17735727 }
2057 else
2058 {
2059
4/4
✓ Branch 0 taken 179102 times.
✓ Branch 1 taken 76859289 times.
✓ Branch 2 taken 51152 times.
✓ Branch 3 taken 127950 times.
77038391 if (cmb.type == cBRIDGE && (cmb.walk&(0x10<<b)))
2060 {
2061 127950 return 0;
2062 }
2063 }
2064
2/2
✓ Branch 0 taken 17735727 times.
✓ Branch 1 taken 76910441 times.
94646168 if (get_qr(qr_NO_SOLID_SWIM))
2065 {
2066
8/14
✓ Branch 0 taken 51152 times.
✓ Branch 1 taken 76859289 times.
✓ Branch 2 taken 51152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 716283 times.
✓ Branch 5 taken 76143006 times.
✓ Branch 6 taken 3461 times.
✓ Branch 7 taken 712822 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3461 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
76910441 if ((cmb.type != cBRIDGE || (!get_qr(qr_OLD_BRIDGE_COMBOS) && !(cmb.walk&(0x10<<b)))) && (cmb.walk&(1<<b)) && !((cmb.usrflags&cflag4) && cmb.type == cWATER && (cmb.walk&(0x10<<b)) && ShallowCheck))
2067 {
2068 716283 return 0;
2069 }
2070 76194158 }
2071
3/6
✓ Branch 0 taken 320336 times.
✓ Branch 1 taken 93609549 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 320336 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
93929885 if (iswater_type(cmb.type) && (cmb.walk&(1<<b)) && ((cmb.usrflags&cflag3) || (cmb.usrflags&cflag4)
2072 || (hero && current_item(itype_flippers) < cmb.attribytes[0])
2073 || (hero && ((cmb.usrflags&cflag1) && !(itemsbuf[current_item_id(itype_flippers)].flags & item_flag3)))))
2074 {
2075 if (!(ShallowCheck && (cmb.walk&(1<<b)) && (cmb.usrflags&cflag4))) return 0;
2076 }
2077 93929885 }
2078
2079 131346201 auto found_ffc_not_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2080
2/2
✓ Branch 0 taken 87334447 times.
✓ Branch 1 taken 527865 times.
87862312 if (ffcIsAt(ffc_handle, tx2, ty2))
2081 {
2082 527865 auto ty = ffc_handle.ctype();
2083
4/6
✓ Branch 0 taken 527865 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144225 times.
✓ Branch 3 taken 383640 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 144225 times.
527865 if(!combo_class_buf[ty].water && !(ShallowCheck && ty == cSHALLOWWATER))
2084 527865 return true;
2085 }
2086
2087 87334447 return false;
2088 87862312 });
2089
2/2
✓ Branch 0 taken 42956024 times.
✓ Branch 1 taken 527865 times.
43483889 if (found_ffc_not_water) return 0;
2090
2091
2/2
✓ Branch 0 taken 14673 times.
✓ Branch 1 taken 42941351 times.
42956024 if(!i)
2092 {
2093 127951877 auto found_ffc_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2094
1/2
✓ Branch 0 taken 85010526 times.
✗ Branch 1 not taken.
85010526 if (ffcIsAt(ffc_handle, tx2, ty2))
2095 {
2096 auto ty = ffc_handle.ctype();
2097 if(combo_class_buf[ty].water || (ShallowCheck && ty == cSHALLOWWATER))
2098 return true;
2099 }
2100
2101 85010526 return false;
2102 85010526 });
2103
1/2
✓ Branch 0 taken 42941351 times.
✗ Branch 1 not taken.
42941351 if (found_ffc_water)
2104 {
2105 if(out_handle) *out_handle = *found_ffc_water;
2106 return found_ffc_water->data();
2107 }
2108 42941351 }
2109
2110 42956024 int32_t checkcombo = MAPCOMBO3(map, screen, layer, tx2, ty2, secrets);
2111
2/2
✓ Branch 0 taken 42911530 times.
✓ Branch 1 taken 44494 times.
42956024 if (!(combobuf[checkcombo].walk&(1<<(b+4)))) return 0;
2112
7/12
✓ Branch 0 taken 42630925 times.
✓ Branch 1 taken 280605 times.
✓ Branch 2 taken 10830561 times.
✓ Branch 3 taken 31800364 times.
✓ Branch 4 taken 10352377 times.
✓ Branch 5 taken 478184 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 10352377 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
42911530 if (iswater_type(combobuf[checkcombo].type)||(ShallowCheck && (combobuf[checkcombo].type == cSHALLOWWATER || (iswater_type(combobuf[checkcombo].type) && (combobuf[checkcombo].walk&(1<<b)) && (combobuf[checkcombo].usrflags&cflag4)))))
2113 {
2114
2/2
✓ Branch 0 taken 1227 times.
✓ Branch 1 taken 757562 times.
758789 if (i == 0)
2115 {
2116
2/2
✓ Branch 0 taken 757553 times.
✓ Branch 1 taken 9 times.
757562 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(tx2, ty2, layer+1);
2117 757562 return checkcombo;
2118 }
2119 1227 }
2120 42153968 }
2121 42139295 return 0;
2122 }
2123 }
2124 else
2125 {
2126 39849461 int32_t b = 0;
2127
2/2
✓ Branch 0 taken 20636412 times.
✓ Branch 1 taken 19213049 times.
39849461 if(x&8) b+=2;
2128
2/2
✓ Branch 0 taken 15456485 times.
✓ Branch 1 taken 24392976 times.
39849461 if(y&8) b+=1;
2129
1/2
✓ Branch 0 taken 39849461 times.
✗ Branch 1 not taken.
39849461 if (get_qr(qr_NO_SOLID_SWIM))
2130 {
2131 if (combobuf[combo].walk&(1<<b))
2132 {
2133 return 0;
2134 }
2135 }
2136
1/2
✓ Branch 0 taken 39849461 times.
✗ Branch 1 not taken.
39849461 if (!(combobuf[combo].walk&(1<<(b+4)))) return 0;
2137
8/8
✓ Branch 0 taken 38150901 times.
✓ Branch 1 taken 1698560 times.
✓ Branch 2 taken 167945 times.
✓ Branch 3 taken 37982956 times.
✓ Branch 4 taken 2129 times.
✓ Branch 5 taken 1782338 times.
✓ Branch 6 taken 163774 times.
✓ Branch 7 taken 161691 times.
39849461 if((iswater_type(combobuf[combo].type) || (ShallowCheck && combobuf[combo].type == cSHALLOWWATER)) && !DRIEDLAKE)
2138 {
2139
2/2
✓ Branch 0 taken 1943999 times.
✓ Branch 1 taken 30 times.
1944029 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, 0); //NOTE: This is only correct assuming 'combo' is 'MAPCOMBO(x,y)'
2140 1944029 return combo;
2141 }
2142 38146730 return 0;
2143 }
2144 97445550 }
2145
2146 326 bool isdamage_type(int32_t type)
2147 {
2148
1/2
✓ Branch 0 taken 326 times.
✗ Branch 1 not taken.
326 switch(type)
2149 {
2150 case cDAMAGE1: case cDAMAGE2: case cDAMAGE3: case cDAMAGE4:
2151 case cDAMAGE5: case cDAMAGE6: case cDAMAGE7:
2152 return true;
2153 }
2154 326 return false;
2155 326 }
2156
2157 2569347297 bool ispitfall_type(int32_t type)
2158 {
2159 2569347297 return combo_class_buf[type].pit != 0;
2160 }
2161
2162 2569347297 bool ispitfall(int32_t combo)
2163 {
2164 2569347297 return ispitfall_type(combobuf[combo].type);
2165 }
2166
2167 278127958 bool ispitfall(int32_t x, int32_t y)
2168 {
2169
2/2
✓ Branch 0 taken 1456039 times.
✓ Branch 1 taken 276671919 times.
278127958 if(int32_t c = MAPFFCOMBO(x,y))
2170 {
2171 1456039 return ispitfall(c) ? true : false;
2172 }
2173 276671919 int32_t c = MAPCOMBOL(2,x,y);
2174
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 276671919 times.
276671919 if(ispitfall(c)) return true;
2175
2/2
✓ Branch 0 taken 263560767 times.
✓ Branch 1 taken 13111152 times.
276671919 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2176 {
2177
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 263560767 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
263560767 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return false;
2178 263560767 }
2179 else
2180 {
2181
3/4
✓ Branch 0 taken 2780 times.
✓ Branch 1 taken 13108372 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2780 times.
13111152 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return false;
2182 }
2183 276669139 c = MAPCOMBOL(1,x,y);
2184
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 276669115 times.
276669139 if(ispitfall(c)) return true;
2185
2186
2/2
✓ Branch 0 taken 263560767 times.
✓ Branch 1 taken 13108348 times.
276669115 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2187 {
2188
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 263560767 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
263560767 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return false;
2189 263560767 }
2190 else
2191 {
2192
4/4
✓ Branch 0 taken 13072 times.
✓ Branch 1 taken 13095276 times.
✓ Branch 2 taken 8777 times.
✓ Branch 3 taken 4295 times.
13108348 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return false;
2193 }
2194 276660338 c = MAPCOMBO(x,y);
2195
2/2
✓ Branch 0 taken 70747 times.
✓ Branch 1 taken 276589591 times.
276660338 if(ispitfall(c)) return true;
2196 276589591 return false;
2197 278127958 }
2198
2199 585542416 int32_t getpitfall(int32_t x, int32_t y) //Return the highest-layer active pit combo at the given position
2200 {
2201
2/2
✓ Branch 0 taken 9281019 times.
✓ Branch 1 taken 576261397 times.
585542416 if(int32_t c = MAPFFCOMBO(x,y))
2202 {
2203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9281019 times.
9281019 return ispitfall(c) ? c : 0;
2204 }
2205 576261397 int32_t c = MAPCOMBOL(2,x,y);
2206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 576261397 times.
576261397 if(ispitfall(c)) return c;
2207
2208
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 43538912 times.
576261397 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2209 {
2210
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return 0;
2211 532722485 }
2212 else
2213 {
2214
3/4
✓ Branch 0 taken 35747 times.
✓ Branch 1 taken 43503165 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 35747 times.
43538912 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return 0;
2215 }
2216 576225650 c = MAPCOMBOL(1,x,y);
2217
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 576225372 times.
576225650 if(ispitfall(c)) return c;
2218
2219
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 43502887 times.
576225372 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2220 {
2221
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return 0;
2222 532722485 }
2223 else
2224 {
2225
4/4
✓ Branch 0 taken 144357 times.
✓ Branch 1 taken 43358530 times.
✓ Branch 2 taken 103729 times.
✓ Branch 3 taken 40628 times.
43502887 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return 0;
2226 }
2227 576121643 c = MAPCOMBO(x,y);
2228
2/2
✓ Branch 0 taken 176844 times.
✓ Branch 1 taken 575944799 times.
576121643 if(ispitfall(c)) return c;
2229 575944799 return 0;
2230 585542416 }
2231 51 optional<combined_handle_t> get_pitfall_handle(int32_t x, int32_t y) //Return the highest-layer active pit combo handle at the given position
2232 {
2233
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(int32_t c = MAPFFCOMBO(x,y))
2234 {
2235 return ispitfall(c) ? getFFCAt(x,y) : nullopt;
2236 }
2237 51 int32_t c = MAPCOMBOL(2,x,y);
2238
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 2);
2239
2240
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 45 times.
51 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2241 {
2242
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1))
2243 return nullopt;
2244 6 }
2245 else
2246 {
2247
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1))
2248 return nullopt;
2249 }
2250 51 c = MAPCOMBOL(1,x,y);
2251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 1);
2252
2253
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 45 times.
51 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2254 {
2255
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0))
2256 return nullopt;
2257 6 }
2258 else
2259 {
2260
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0))
2261 return nullopt;
2262 }
2263 51 c = MAPCOMBO(x,y);
2264
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 0);
2265 return nullopt;
2266 51 }
2267 5426640 bool check_icy(newcombo const& cmb, int type)
2268 {
2269
2/2
✓ Branch 0 taken 5426475 times.
✓ Branch 1 taken 165 times.
5426640 if(cmb.type != cICY)
2270 5426475 return false;
2271
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 165 times.
165 switch(type)
2272 {
2273 case ICY_BLOCK:
2274 return cmb.usrflags&cflag1;
2275 case ICY_PLAYER:
2276 165 return cmb.usrflags&cflag2;
2277 }
2278 return false;
2279 5426640 }
2280 1811404 int get_icy(int x, int y, int type)
2281 {
2282 1811404 int32_t c = MAPCOMBOL(2,x,y);
2283
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1811404 times.
1811404 if(check_icy(combobuf[c], type)) return c;
2284
2285 1811404 int screen = get_screen_for_world_xy(x, y);
2286
2287 1811404 mapscr* scr = get_scr_layer_valid(screen, 2);
2288
2/2
✓ Branch 0 taken 4618 times.
✓ Branch 1 taken 1806786 times.
1811404 if (scr)
2289 {
2290
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 1806270 times.
1806786 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2291 {
2292
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 516 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
516 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2293 516 }
2294 else
2295 {
2296
3/4
✓ Branch 0 taken 3048 times.
✓ Branch 1 taken 1803222 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3048 times.
1806270 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2297 }
2298 1803738 }
2299 1808356 c = MAPCOMBOL(1,x,y);
2300
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1808356 times.
1808356 if(check_icy(combobuf[c], type)) return c;
2301
2302 1808356 scr = get_scr_layer_valid(screen, 1);
2303
2/2
✓ Branch 0 taken 2427 times.
✓ Branch 1 taken 1805929 times.
1808356 if (scr)
2304 {
2305
2/2
✓ Branch 0 taken 1934 times.
✓ Branch 1 taken 1803995 times.
1805929 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2306 {
2307
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1934 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1934 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2308 1934 }
2309 else
2310 {
2311
3/4
✓ Branch 0 taken 1641 times.
✓ Branch 1 taken 1802354 times.
✓ Branch 2 taken 1641 times.
✗ Branch 3 not taken.
1803995 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2312 }
2313 1804288 }
2314 1806715 c = MAPCOMBO(x,y);
2315
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1806715 times.
1806715 if(check_icy(combobuf[c], type)) return c;
2316 1806715 return 0;
2317 1811404 }
2318
2319 13049036 static bool checkSV(int32_t x, int32_t y, int32_t flag)
2320 {
2321
8/8
✓ Branch 0 taken 13042238 times.
✓ Branch 1 taken 6798 times.
✓ Branch 2 taken 13033372 times.
✓ Branch 3 taken 8866 times.
✓ Branch 4 taken 13021740 times.
✓ Branch 5 taken 11632 times.
✓ Branch 6 taken 428468 times.
✓ Branch 7 taken 12593272 times.
13049036 if(x<0 || x>=world_w || y<0 || y>=world_h)
2322 455764 return false;
2323
2324 12593272 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
2325
2/4
✓ Branch 0 taken 12593272 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12593272 times.
12593272 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2326 return true;
2327
2328 12593272 change_rpos_handle_layer(rpos_handle, 1);
2329
2/2
✓ Branch 0 taken 7560354 times.
✓ Branch 1 taken 5032918 times.
12593272 if (rpos_handle.scr->is_valid())
2330
3/4
✓ Branch 0 taken 5032918 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3279 times.
✓ Branch 3 taken 5029639 times.
5032918 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2331 3279 return true;
2332
2333 12589993 change_rpos_handle_layer(rpos_handle, 2);
2334
2/2
✓ Branch 0 taken 10831908 times.
✓ Branch 1 taken 1758085 times.
12589993 if (rpos_handle.scr->is_valid())
2335
2/4
✓ Branch 0 taken 1758085 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1758085 times.
1758085 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2336 return true;
2337
2338 12589993 return false;
2339 13049036 }
2340
2341 6588680 bool isSVLadder(int32_t x, int32_t y)
2342 {
2343 6588680 return checkSV(x, y, mfSIDEVIEWLADDER);
2344 }
2345
2346 6460356 bool isSVPlatform(int32_t x, int32_t y)
2347 {
2348 6460356 return checkSV(x, y, mfSIDEVIEWPLATFORM);
2349 }
2350
2351 6460356 bool checkSVLadderPlatform(int32_t x, int32_t y)
2352 {
2353
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6460356 times.
✓ Branch 2 taken 6458559 times.
✓ Branch 3 taken 1797 times.
6460356 return isSVPlatform(x,y) || (isSVLadder(x,y) && !isSVLadder(x,y-16));
2354 }
2355
2356 1637 bool isstepable(int32_t combo) //can use ladder on it
2357 {
2358
2/2
✓ Branch 0 taken 1631 times.
✓ Branch 1 taken 6 times.
1637 if(combo_class_buf[combobuf[combo].type].ladder_pass) return true;
2359
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(combo_class_buf[combobuf[combo].type].pit)
2360 {
2361 if(combobuf[combo].usrflags&cflag4)
2362 {
2363 int32_t ldrid = current_item_id(itype_ladder);
2364 return (ldrid > -1 && itemsbuf[ldrid].flags & item_flag1);
2365 }
2366 }
2367 6 return false;
2368 1637 }
2369
2370 32780 bool isHSGrabbable(newcombo const& cmb)
2371 {
2372
2/2
✓ Branch 0 taken 373 times.
✓ Branch 1 taken 32407 times.
32780 if(cmb.type == cHSGRAB) return true;
2373 32407 return cmb.genflags & cflag1;
2374 32780 }
2375
2376 954 bool isSwitchHookable(newcombo const& cmb)
2377 {
2378
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 822 times.
954 if(cmb.type == cSWITCHHOOK) return true;
2379 822 return cmb.genflags & cflag2;
2380 954 }
2381
2382 61401 bool check_hshot(int32_t layer, int32_t x, int32_t y, bool switchhook, rpos_t *out_rpos, ffcdata **out_ffc)
2383 {
2384 61401 rpos_t cpos = rpos_t::None;
2385
2/2
✓ Branch 0 taken 64592 times.
✓ Branch 1 taken 125993 times.
61401 if(out_rpos)
2386 {
2387 125993 int32_t id = MAPCOMBO2(layer-1,x,y);
2388
2/2
✓ Branch 0 taken 28634 times.
✓ Branch 1 taken 97359 times.
125993 if(id > 0)
2389 {
2390 97359 newcombo const& cmb = combobuf[id];
2391
4/4
✓ Branch 0 taken 32738 times.
✓ Branch 1 taken 64621 times.
✓ Branch 2 taken 32296 times.
✓ Branch 3 taken 32325 times.
97359 cpos = (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb)) ? COMBOPOS_REGION(x,y) : rpos_t::None;
2392 32767 }
2393 61401 }
2394
2395 125993 ffcdata* ffc = nullptr;
2396
4/4
✓ Branch 0 taken 28389 times.
✓ Branch 1 taken 97604 times.
✓ Branch 2 taken 24996 times.
✓ Branch 3 taken 3393 times.
125993 if (out_ffc && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2397 {
2398 10359 for_some_ffcs([&](const ffc_handle_t& ffc_handle) {
2399
2/2
✓ Branch 0 taken 6853 times.
✓ Branch 1 taken 113 times.
6966 if (ffcIsAt(ffc_handle, x, y))
2400 {
2401 113 auto& cmb = ffc_handle.combo();
2402
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 71 times.
✓ Branch 2 taken 35 times.
✓ Branch 3 taken 36 times.
113 if (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb))
2403 {
2404 77 ffc = ffc_handle.ffc;
2405 77 return false;
2406 }
2407 36 }
2408 6889 return true;
2409 6896 });
2410 3393 }
2411
2412
4/4
✓ Branch 0 taken 61401 times.
✓ Branch 1 taken 64592 times.
✓ Branch 2 taken 442 times.
✓ Branch 3 taken 60959 times.
125993 if (out_rpos && cpos != rpos_t::None) *out_rpos = cpos;
2413
4/4
✓ Branch 0 taken 28389 times.
✓ Branch 1 taken 97604 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 28382 times.
125993 if (out_ffc && ffc) *out_ffc = ffc;
2414
2/2
✓ Branch 0 taken 65034 times.
✓ Branch 1 taken 60959 times.
125993 return (cpos != rpos_t::None || ffc);
2415 }
2416
2417 5195 bool ishookshottable(int32_t bx, int32_t by)
2418 {
2419
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5195 times.
5195 if(!_walkflag(bx,by,1))
2420 return true;
2421
2422
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5187 times.
5195 if (collide_object(bx, by, 1, 1))
2423 8 return false;
2424
2425 5187 bool ret = true;
2426
2/2
✓ Branch 0 taken 15561 times.
✓ Branch 1 taken 1900 times.
17461 for(int32_t i=2; i>=0; i--)
2427 {
2428 15561 int32_t c = MAPCOMBO2(i-1,bx,by);
2429 15561 int32_t t = combobuf[c].type;
2430
2431
6/6
✓ Branch 0 taken 5187 times.
✓ Branch 1 taken 10374 times.
✓ Branch 2 taken 3853 times.
✓ Branch 3 taken 1334 times.
✓ Branch 4 taken 1900 times.
✓ Branch 5 taken 1953 times.
15561 if(i == 0 && (t == cHOOKSHOTONLY || t == cLADDERHOOKSHOT)) return true;
2432
2433
3/4
✓ Branch 0 taken 11321 times.
✓ Branch 1 taken 953 times.
✓ Branch 2 taken 953 times.
✗ Branch 3 not taken.
13227 bool dried = (iswater_type(t) && DRIEDLAKE);
2434
2435 12274 int32_t b=1;
2436
2437
2/2
✓ Branch 0 taken 6109 times.
✓ Branch 1 taken 6165 times.
12274 if(bx&8) b<<=2;
2438
2439
2/2
✓ Branch 0 taken 3841 times.
✓ Branch 1 taken 8433 times.
12274 if(by&8) b<<=1;
2440
2441
7/8
✓ Branch 0 taken 2094 times.
✓ Branch 1 taken 10180 times.
✓ Branch 2 taken 2094 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1115 times.
✓ Branch 5 taken 979 times.
✓ Branch 6 taken 75 times.
✓ Branch 7 taken 904 times.
12274 if(combobuf[c].walk&b && !dried && !(combo_class_buf[t].ladder_pass && t!=cLADDERONLY) && t!=cHOOKSHOTONLY)
2442 904 ret = false;
2443 12274 }
2444
2445 1900 return ret;
2446 5195 }
2447
2448 10110 bool reveal_hidden_stairs(mapscr *s, int32_t screen, bool redraw)
2449 {
2450
4/4
✓ Branch 0 taken 9531 times.
✓ Branch 1 taken 579 times.
✓ Branch 2 taken 9531 times.
✓ Branch 3 taken 579 times.
10110 if((s->stairx || s->stairy) && s->secretcombo[sSTAIRS])
2451 {
2452 579 int pos = COMBOPOS(s->stairx,s->stairy);
2453 579 s->data[pos] = s->secretcombo[sSTAIRS];
2454 579 s->cset[pos] = s->secretcset[sSTAIRS];
2455 579 s->sflag[pos] = s->secretflag[sSTAIRS];
2456
2457
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 323 times.
579 if (redraw)
2458 {
2459 768 auto [x, y] = translate_screen_coordinates_to_world(screen, s->stairx, s->stairy);
2460 768 putcombo(scrollbuf,x,y,s->data[pos],s->cset[pos]);
2461 256 }
2462
2463 579 return true;
2464 }
2465
2466 9531 return false;
2467 10110 }
2468
2469 51230 screen_handles_t create_screen_handles_one(mapscr* base_scr)
2470 {
2471 DCHECK(base_scr->is_valid());
2472
2473 51230 screen_handles_t screen_handles{};
2474 51230 screen_handles[0] = {base_scr, base_scr, base_scr->screen, 0};
2475 51230 return screen_handles;
2476 }
2477
2478 56531351 screen_handles_t create_screen_handles(mapscr* base_scr)
2479 {
2480 DCHECK(get_scr(base_scr->screen) == base_scr);
2481 DCHECK(base_scr->is_valid());
2482
2483 56531351 int screen = base_scr->screen;
2484 screen_handles_t screen_handles;
2485 56531351 screen_handles[0] = {base_scr, base_scr, screen, 0};
2486
2/2
✓ Branch 0 taken 339188106 times.
✓ Branch 1 taken 56531351 times.
395719457 for (int i = 1; i <= 6; i++)
2487 339188106 screen_handles[i] = {base_scr, get_scr_layer_valid(screen, i), screen, i};
2488 56531351 return screen_handles;
2489 }
2490
2491 106202 bool remove_screenstatecombos2(const screen_handles_t& screen_handles, bool do_layers, int32_t what1, int32_t what2)
2492 {
2493 106202 mapscr* scr = screen_handles[0].scr;
2494 106202 bool didit=false;
2495
2496
2/2
✓ Branch 0 taken 106202 times.
✓ Branch 1 taken 18691552 times.
18797754 for(int32_t i=0; i<176; i++)
2497 {
2498 18691552 newcombo const& cmb = combobuf[scr->data[i]];
2499
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 18691226 times.
18691552 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2500
4/4
✓ Branch 0 taken 18689693 times.
✓ Branch 1 taken 1533 times.
✓ Branch 2 taken 1102 times.
✓ Branch 3 taken 18688591 times.
18691226 if((cmb.type == what1) || (cmb.type== what2))
2501 {
2502 2635 scr->data[i]++;
2503 2635 didit=true;
2504 2635 }
2505 18691226 }
2506
2507
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 106110 times.
106202 if (do_layers)
2508 {
2509
2/2
✓ Branch 0 taken 636660 times.
✓ Branch 1 taken 106110 times.
742770 for(int32_t j=1; j<=6; j++)
2510 {
2511 636660 mapscr* layer_scr = screen_handles[j].scr;
2512
2/2
✓ Branch 0 taken 173130 times.
✓ Branch 1 taken 463530 times.
636660 if (!layer_scr) continue;
2513
2514
2/2
✓ Branch 0 taken 30470880 times.
✓ Branch 1 taken 173130 times.
30644010 for(int32_t i=0; i<176; i++)
2515 {
2516 30470880 newcombo const& cmb = combobuf[layer_scr->data[i]];
2517
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30470880 times.
30470880 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2518
4/4
✓ Branch 0 taken 30470797 times.
✓ Branch 1 taken 83 times.
✓ Branch 2 taken 265 times.
✓ Branch 3 taken 30470532 times.
30470880 if((cmb.type== what1) || (cmb.type== what2))
2519 {
2520 348 layer_scr->data[i]++;
2521 348 didit=true;
2522 348 }
2523 30470880 }
2524 173130 }
2525 106110 }
2526
2527 // 'do_layers' also means that this is called on an active temp screen, so update its ffcs.
2528
3/4
✓ Branch 0 taken 20406 times.
✓ Branch 1 taken 85796 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20406 times.
106202 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && do_layers)
2529 {
2530 20406 word c = scr->numFFC();
2531
2/2
✓ Branch 0 taken 73350 times.
✓ Branch 1 taken 20406 times.
93756 for(word i=0; i<c; i++)
2532 {
2533 73350 ffcdata* ffc = &scr->ffcs[i];
2534 73350 newcombo const& cmb = combobuf[ffc->data];
2535
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73350 times.
73350 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2536
2/4
✓ Branch 0 taken 73350 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 73350 times.
73350 if((cmb.type== what1) || (cmb.type== what2))
2537 {
2538 zc_ffc_modify(*ffc, 1);
2539 didit=true;
2540 }
2541 73350 }
2542 20406 }
2543
2544 106202 return didit;
2545 }
2546
2547 14 bool remove_xstatecombos(const screen_handles_t& screen_handles, byte xflag, bool triggers)
2548 {
2549 14 int screen = screen_handles[0].scr->screen;
2550
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2551 14 return remove_xstatecombos_mi(screen_handles, mi, xflag, triggers);
2552 }
2553 471478990 bool remove_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, byte xflag, bool triggers)
2554 {
2555 471478990 bool didit=false;
2556
2/2
✓ Branch 0 taken 471450132 times.
✓ Branch 1 taken 28858 times.
471478990 if(!getxmapflag_mi(mi, 1<<xflag)) return false;
2557
2558 28858 mapscr* s = screen_handles[0].scr;
2559 28858 int screen = s->screen;
2560 28858 bool is_active_screen = is_in_current_region(s);
2561
2562 24317386 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2563
4/4
✓ Branch 0 taken 11264 times.
✓ Branch 1 taken 24277264 times.
✓ Branch 2 taken 1808 times.
✓ Branch 3 taken 24286720 times.
24288528 if(triggers && force_ex_trigger_any(rpos_handle, xflag))
2564 1808 didit = true;
2565
2/2
✓ Branch 0 taken 63627 times.
✓ Branch 1 taken 24223093 times.
24286720 else switch (rpos_handle.ctype())
2566 {
2567 case cLOCKBLOCK: case cLOCKBLOCK2:
2568 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2569 case cCHEST: case cCHEST2:
2570 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2571 case cBOSSCHEST: case cBOSSCHEST2:
2572 {
2573 63627 auto& cmb = rpos_handle.combo();
2574
2/2
✓ Branch 0 taken 62059 times.
✓ Branch 1 taken 1568 times.
63627 if(!(cmb.usrflags&cflag16)) return; //custom state instead of normal state
2575
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 62030 times.
62059 if(cmb.attribytes[5] == xflag)
2576 {
2577 29 rpos_handle.increment_data();
2578 29 didit=true;
2579 29 }
2580 62059 break;
2581 }
2582 }
2583 24288528 });
2584
2585
4/4
✓ Branch 0 taken 28817 times.
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 19197 times.
✓ Branch 3 taken 9620 times.
28858 if (is_active_screen && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2586 {
2587 19197 word c = s->numFFC();
2588 19197 int screen_index_offset = get_region_screen_offset(screen);
2589
2/2
✓ Branch 0 taken 36840 times.
✓ Branch 1 taken 19197 times.
56037 for (uint8_t i = 0; i < c; i++)
2590 {
2591 36840 auto ffc_handle = *s->getFFCHandle(i, screen_index_offset);
2592 36840 auto& cmb = ffc_handle.combo();
2593
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 36840 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 36824 times.
36840 if(triggers && force_ex_trigger_any(ffc_handle, xflag))
2594 16 didit = true;
2595
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36824 times.
36824 else switch(cmb.type)
2596 {
2597 case cLOCKBLOCK: case cLOCKBLOCK2:
2598 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2599 case cCHEST: case cCHEST2:
2600 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2601 case cBOSSCHEST: case cBOSSCHEST2:
2602 {
2603 if(!(cmb.usrflags&cflag16)) continue; //custom state instead of normal state
2604 if(cmb.attribytes[5] == xflag)
2605 {
2606 zc_ffc_modify(*ffc_handle.ffc, 1);
2607 didit=true;
2608 }
2609 break;
2610 }
2611 }
2612 36840 }
2613 19197 }
2614
2615 28858 return didit;
2616 471478990 }
2617
2618 14682265 void clear_xstatecombos(const screen_handles_t& screen_handles, bool triggers)
2619 {
2620 14682265 int screen = screen_handles[0].screen;
2621
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14294432 times.
14682265 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2622 14682265 clear_xstatecombos_mi(screen_handles, mi, triggers);
2623 14682265 }
2624
2625 14733718 void clear_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2626 {
2627
2/2
✓ Branch 0 taken 471478976 times.
✓ Branch 1 taken 14733718 times.
486212694 for (int q = 0; q < 32; ++q)
2628 {
2629 471478976 remove_xstatecombos_mi(screen_handles, mi, q, triggers);
2630 471478976 }
2631 14733718 }
2632
2633 bool remove_xdoors(const screen_handles_t& screen_handles, uint dir, uint ind, bool triggers)
2634 {
2635 int screen = screen_handles[0].screen;
2636 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2637 return remove_xdoors_mi(screen_handles, mi, dir, ind, triggers);
2638 }
2639 471478976 bool remove_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, uint dir, uint ind, bool triggers)
2640 {
2641 471478976 bool didit=false;
2642
2/2
✓ Branch 0 taken 471477663 times.
✓ Branch 1 taken 1313 times.
471478976 if (!getxdoor_mi(mi, dir, ind)) return false;
2643
2644 1313 mapscr* scr = screen_handles[0].scr;
2645 1313 int screen = scr->screen;
2646 1313 bool is_active_screen = is_in_current_region(scr);
2647
2648 925665 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2649
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 924352 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 924341 times.
924352 if (triggers && force_ex_door_trigger_any(rpos_handle, dir, ind))
2650 11 didit = true;
2651 else; //future door combo types?
2652 924352 });
2653
2654
2/4
✓ Branch 0 taken 1313 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1313 times.
✗ Branch 3 not taken.
1313 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && is_active_screen)
2655 {
2656 1313 word c = scr->numFFC();
2657 1313 int screen_index_offset = get_region_screen_offset(screen);
2658
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1313 times.
1313 for (uint8_t i = 0; i < c; i++)
2659 {
2660 auto ffc_handle = *scr->getFFCHandle(i, screen_index_offset);
2661 if (triggers && force_ex_door_trigger_any(ffc_handle, dir, ind))
2662 didit = true;
2663 else; //future door combo types?
2664 }
2665 1313 }
2666
2667 1313 return didit;
2668 471478976 }
2669
2670 14682265 void clear_xdoors(const screen_handles_t& screen_handles, bool triggers)
2671 {
2672 14682265 int screen = screen_handles[0].screen;
2673
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14294432 times.
14682265 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2674 14682265 return clear_xdoors_mi(screen_handles, mi, triggers);
2675 }
2676
2677 14733718 void clear_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2678 {
2679
2/2
✓ Branch 0 taken 58934872 times.
✓ Branch 1 taken 14733718 times.
73668590 for (int dir = 0; dir < 4; ++dir)
2680
2/2
✓ Branch 0 taken 471478976 times.
✓ Branch 1 taken 58934872 times.
530413848 for (int q = 0; q < 8; ++q)
2681 530413848 remove_xdoors_mi(screen_handles, mi, dir, q, triggers);
2682 14733718 }
2683
2684 763 bool remove_lockblocks(const screen_handles_t& screen_handles)
2685 {
2686 763 return remove_screenstatecombos2(screen_handles, true, cLOCKBLOCK, cLOCKBLOCK2);
2687 }
2688
2689 98 bool remove_bosslockblocks(const screen_handles_t& screen_handles)
2690 {
2691 98 return remove_screenstatecombos2(screen_handles, true, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
2692 }
2693
2694 76553 bool remove_chests(const screen_handles_t& screen_handles)
2695 {
2696 76553 return remove_screenstatecombos2(screen_handles, true, cCHEST, cCHEST2);
2697 }
2698
2699 2484 bool remove_lockedchests(const screen_handles_t& screen_handles)
2700 {
2701 2484 return remove_screenstatecombos2(screen_handles, true, cLOCKEDCHEST, cLOCKEDCHEST2);
2702 }
2703
2704 26212 bool remove_bosschests(const screen_handles_t& screen_handles)
2705 {
2706 26212 return remove_screenstatecombos2(screen_handles, true, cBOSSCHEST, cBOSSCHEST2);
2707 }
2708
2709 1384361 void delete_fireball_shooter(const rpos_handle_t& rpos_handle)
2710 {
2711 1384361 int32_t ct=rpos_handle.ctype();
2712
2713
6/6
✓ Branch 0 taken 1383741 times.
✓ Branch 1 taken 620 times.
✓ Branch 2 taken 1383489 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 1383381 times.
✓ Branch 5 taken 108 times.
1384361 if(ct!=cL_STATUE && ct!=cR_STATUE && ct!=cC_STATUE)
2714 1383381 return;
2715
2716 2465 auto [cx, cy] = rpos_handle.xy();
2717
3/4
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 620 times.
✓ Branch 3 taken 108 times.
980 switch(ct)
2718 {
2719 case cL_STATUE:
2720 620 cx += 4;
2721 620 cy += 7;
2722 620 break;
2723
2724 case cR_STATUE:
2725 252 cx -= 8;
2726 252 cy -= 1;
2727 252 break;
2728
2729 case cC_STATUE:
2730 108 break;
2731 }
2732
2733
2/2
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 1485 times.
2465 for(int32_t j=0; j<guys.Count(); j++)
2734 {
2735 // Finds the smallest enemy ID
2736
9/10
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 1086 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 1086 times.
✓ Branch 4 taken 346 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 53 times.
✓ Branch 8 taken 346 times.
✗ Branch 9 not taken.
2970 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy)&&(guysbuf[(guys.spr(j)->id)&0xFFF].flags & guy_fire))
2737 {
2738 346 guys.del(j);
2739 346 }
2740 1485 }
2741 1384361 }
2742
2743 15 static int32_t findtrigger(int32_t screen)
2744 {
2745 15 int32_t checkflag=0;
2746 15 int32_t ret = 0;
2747
2748 mapscr* screens[7];
2749
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 15 times.
120 for (int32_t j = 0; j <= 6; j++)
2750 {
2751 105 screens[j] = get_scr_layer_valid(screen, j);
2752 105 }
2753
2754 15 bool sflag = false;
2755
2/2
✓ Branch 0 taken 2640 times.
✓ Branch 1 taken 15 times.
2655 for(word j=0; j<176; j++)
2756 {
2757
2/2
✓ Branch 0 taken 26752 times.
✓ Branch 1 taken 2640 times.
29392 for(int32_t layer = -1; layer < 6; ++layer)
2758 {
2759 26752 mapscr* scr = screens[layer+1];
2760
2/2
✓ Branch 0 taken 16544 times.
✓ Branch 1 taken 10208 times.
26752 if (!scr) continue;
2761
2762
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if(sflag)
2763 8272 checkflag = scr->sflag[j];
2764 else
2765 8272 checkflag = combobuf[scr->data[j]].flag;
2766 16544 sflag = !sflag;
2767
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if (sflag) --layer;
2768
2769
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 16534 times.
16544 switch(checkflag)
2770 {
2771 case mfANYFIRE:
2772 case mfSTRONGFIRE:
2773 case mfMAGICFIRE:
2774 case mfDIVINEFIRE:
2775 case mfARROW:
2776 case mfSARROW:
2777 case mfGARROW:
2778 case mfSBOMB:
2779 case mfBOMB:
2780 case mfBRANG:
2781 case mfMBRANG:
2782 case mfFBRANG:
2783 case mfWANDMAGIC:
2784 case mfREFMAGIC:
2785 case mfREFFIREBALL:
2786 case mfSWORD:
2787 case mfWSWORD:
2788 case mfMSWORD:
2789 case mfXSWORD:
2790 case mfSWORDBEAM:
2791 case mfWSWORDBEAM:
2792 case mfMSWORDBEAM:
2793 case mfXSWORDBEAM:
2794 case mfHOOKSHOT:
2795 case mfWAND:
2796 case mfHAMMER:
2797 case mfSTRIKE:
2798 10 ret += 1;
2799 10 break;
2800 }
2801 16544 }
2802 2640 }
2803
2804 15 return ret;
2805 }
2806
2807 11738 static void log_trigger_secret_reason(TriggerSource source)
2808 {
2809
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11299 times.
11738 if (source == TriggerSource::Singular)
2810 {
2811 439 Z_eventlog("Restricted Screen Secrets triggered\n");
2812 439 }
2813 else
2814 {
2815 11299 const char* source_str = "";
2816
7/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7178 times.
✓ Branch 3 taken 856 times.
✓ Branch 4 taken 2733 times.
✓ Branch 5 taken 475 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 52 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
11299 switch (source)
2817 {
2818 case TriggerSource::Singular: break;
2819 7178 case TriggerSource::Unspecified: source_str = "unspecified means"; break;
2820 856 case TriggerSource::EnemiesScreenFlag: source_str = "the 'Enemies->Secret' screen flag"; break;
2821 2733 case TriggerSource::SecretsScreenState: source_str = "the 'Secrets' screen state"; break;
2822 475 case TriggerSource::Script: source_str = "a script"; break;
2823 1 case TriggerSource::ItemsSecret: source_str = "Items->Secrets"; break;
2824 52 case TriggerSource::GenericCombo: source_str = "Generic Combo"; break;
2825 4 case TriggerSource::LightTrigger: source_str = "Light Triggers"; break;
2826 case TriggerSource::SCC: source_str = "SCC"; break;
2827 case TriggerSource::CheatTemp: source_str = "Cheat (Temp)"; break;
2828 case TriggerSource::CheatPerm: source_str = "Cheat (Perm)"; break;
2829 }
2830 11299 Z_eventlog("Screen Secrets triggered by %s\n", source_str);
2831 }
2832 11738 }
2833
2834 // single:
2835 // >-1 : the singular triggering combo
2836 // -1: triggered by some other cause
2837 11530 void trigger_secrets_for_screen(TriggerSource source, mapscr* scr, bool high16only, int32_t single)
2838 {
2839 11530 log_trigger_secret_reason(source);
2840
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11091 times.
11530 if (single < 0)
2841 11091 get_screen_state(scr->screen).triggered_secrets = true;
2842
2843 11530 bool do_replay_comment = true;
2844 11530 bool from_active_screen = true;
2845 11530 trigger_secrets_for_screen_internal(create_screen_handles(scr), from_active_screen, high16only, single, do_replay_comment);
2846
2847 // Respect secret state carryovers for active screens.
2848
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11091 times.
11530 if (single >= 0) return;
2849
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 11068 times.
11091 if(scr->nocarry&mSECRET) return;
2850 11068 int cmap = scr->map;
2851 11068 int cscr = scr->screen;
2852 11068 int nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
2853 11068 int nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
2854
2855 11068 std::vector<int32_t> done;
2856
2/2
✓ Branch 0 taken 10896 times.
✓ Branch 1 taken 172 times.
11068 bool looped = (nmap==cmap+1 && nscr==cscr);
2857
2858
6/6
✓ Branch 0 taken 484 times.
✓ Branch 1 taken 11001 times.
✓ Branch 2 taken 67 times.
✓ Branch 3 taken 417 times.
✓ Branch 4 taken 417 times.
✓ Branch 5 taken 11068 times.
11485 while((nmap!=0) && !looped && !(nscr>=128))
2859 {
2860
7/8
✓ Branch 0 taken 317 times.
✓ Branch 1 taken 100 times.
✓ Branch 2 taken 74 times.
✓ Branch 3 taken 243 times.
✓ Branch 4 taken 74 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 70 times.
417 if (nmap - 1 == cur_map && is_in_current_region(nscr) && !get_screen_state(nscr).triggered_secrets)
2861 {
2862
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
2863
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 trigger_secrets_for_screen_internal(create_screen_handles(get_scr(nscr)), from_active_screen, high16only, single, do_replay_comment);
2864
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 get_screen_state(nscr).triggered_secrets = true;
2865 4 }
2866
2867 417 cmap=nmap;
2868 417 cscr=nscr;
2869 417 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
2870 417 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
2871
2872
2/2
✓ Branch 0 taken 386 times.
✓ Branch 1 taken 417 times.
803 for(auto it = done.begin(); it != done.end(); it++)
2873 {
2874
2/2
✓ Branch 0 taken 319 times.
✓ Branch 1 taken 67 times.
386 if(*it == ((nmap-1)<<7)+nscr)
2875 67 looped = true;
2876 386 }
2877
2878
1/2
✓ Branch 0 taken 417 times.
✗ Branch 1 not taken.
417 done.push_back(((nmap-1)<<7)+nscr);
2879 }
2880 11530 }
2881
2882 2437 void trigger_secrets_for_screen(TriggerSource source, int32_t screen, bool high16only, int32_t single)
2883 {
2884 2437 trigger_secrets_for_screen(source, get_scr(screen), high16only, single);
2885 2437 }
2886
2887 18007 void trigger_secrets_for_screen_internal(const screen_handles_t& screen_handles, bool from_active_screen, bool high16only, int32_t single, bool do_replay_comment)
2888 {
2889 18007 mapscr* scr = screen_handles[0].scr;
2890 18007 int screen = scr->screen;
2891
2892 // TODO(replays): No real reason for "do_replay_comment" to exist - I just did not want to update many replays when fixing
2893 // slopes in sideview mode (which required loading nearby screens in loadscr).
2894 // TODO(replays): This should just use `screen`.
2895
3/4
✓ Branch 0 taken 18007 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 539 times.
✓ Branch 3 taken 17468 times.
18007 if (replay_is_active() && do_replay_comment)
2896
4/6
✓ Branch 0 taken 11534 times.
✓ Branch 1 taken 5934 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11534 times.
✓ Branch 4 taken 17468 times.
✗ Branch 5 not taken.
17468 replay_step_comment(fmt::format("trigger secrets scr={}", from_active_screen && scr != special_warp_return_scr ? screen : cur_screen));
2897
2898
2/2
✓ Branch 0 taken 6473 times.
✓ Branch 1 taken 11534 times.
18007 if (from_active_screen)
2899 {
2900 5529590 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
2901
2/4
✓ Branch 0 taken 5516368 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1688 times.
✗ Branch 3 not taken.
5834885 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
2902 316829 return trig.trigger_flags.get(TRIGFLAG_SECRETSTR);
2903 }, ctrigSECRETS);
2904 5518056 });
2905 11534 }
2906
2907 18007 int32_t ft=0; //Flag trigger?
2908 18007 int32_t msflag=0; // Misc. secret flag
2909
2910
2/2
✓ Branch 0 taken 3169232 times.
✓ Branch 1 taken 18007 times.
3187239 for(int32_t i=0; i<176; i++) //Do the 'trigger flags' (non 16-31)
2911 {
2912
4/4
✓ Branch 0 taken 77264 times.
✓ Branch 1 taken 3091968 times.
✓ Branch 2 taken 439 times.
✓ Branch 3 taken 76825 times.
3169232 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2913
2914 // Remember the misc. secret flag; if triggered, use this instead
2915
4/4
✓ Branch 0 taken 114511 times.
✓ Branch 1 taken 2977896 times.
✓ Branch 2 taken 49462 times.
✓ Branch 3 taken 65049 times.
3092407 if(scr->sflag[i]>=mfSECRETS01 && scr->sflag[i]<=mfSECRETS16)
2916 65049 msflag=sSECRET01+(scr->sflag[i]-mfSECRETS01);
2917
4/4
✓ Branch 0 taken 47230 times.
✓ Branch 1 taken 2980128 times.
✓ Branch 2 taken 46999 times.
✓ Branch 3 taken 231 times.
3027358 else if(combobuf[scr->data[i]].flag>=mfSECRETS01 && combobuf[scr->data[i]].flag<=mfSECRETS16)
2918 231 msflag=sSECRET01+(combobuf[scr->data[i]].flag-mfSECRETS01);
2919 else
2920 3027127 msflag=0;
2921
2922
4/4
✓ Branch 0 taken 921256 times.
✓ Branch 1 taken 2171151 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 921184 times.
3092407 if(!high16only || single>=0)
2923 {
2924 2171223 int32_t newflag = -1;
2925
2926
2/2
✓ Branch 0 taken 4342446 times.
✓ Branch 1 taken 2171223 times.
6513669 for(int32_t iter=0; iter<2; ++iter)
2927 {
2928 4342446 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2929
2930
2/2
✓ Branch 0 taken 2171223 times.
✓ Branch 1 taken 2171223 times.
4342446 if(iter==1) checkflag=scr->sflag[i]; //Placed
2931
2932 4342446 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2933
2/2
✓ Branch 0 taken 4330212 times.
✓ Branch 1 taken 12234 times.
4342446 if (ft != -1) //Change the combos for the secret
2934 {
2935 // Use misc. secret flag instead if one is present
2936
2/2
✓ Branch 0 taken 12202 times.
✓ Branch 1 taken 32 times.
12234 if(msflag!=0)
2937 32 ft=msflag;
2938
2939 12234 rpos_handle_t rpos_handle;
2940
2/2
✓ Branch 0 taken 6367 times.
✓ Branch 1 taken 5867 times.
12234 if (from_active_screen)
2941 {
2942 5867 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2943 5867 screen_combo_modify_preroutine(rpos_handle);
2944 5867 }
2945
2946
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12234 times.
12234 if(ft==sSECNEXT)
2947 {
2948 scr->data[i]++;
2949 }
2950 else
2951 {
2952 12234 scr->data[i] = scr->secretcombo[ft];
2953 12234 scr->cset[i] = scr->secretcset[ft];
2954 }
2955 12234 newflag = scr->secretflag[ft];
2956
2957
2/2
✓ Branch 0 taken 6367 times.
✓ Branch 1 taken 5867 times.
12234 if (from_active_screen)
2958 5867 screen_combo_modify_postroutine(rpos_handle);
2959 12234 }
2960 4342446 }
2961
2962
2/2
✓ Branch 0 taken 2158995 times.
✓ Branch 1 taken 12228 times.
2171223 if(newflag >-1) scr->sflag[i] = newflag; //Tiered secret
2963
2964
2/2
✓ Branch 0 taken 13027338 times.
✓ Branch 1 taken 2171223 times.
15198561 for(int32_t j=1; j<=6; j++) //Layers
2965 {
2966 13027338 mapscr* layer_scr = screen_handles[j].scr;
2967
2/2
✓ Branch 0 taken 3213077 times.
✓ Branch 1 taken 9814261 times.
13027338 if (!layer_scr) continue;
2968
2969
3/4
✓ Branch 0 taken 725 times.
✓ Branch 1 taken 3212352 times.
✓ Branch 2 taken 725 times.
✗ Branch 3 not taken.
3213077 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2970
2971 3213077 int32_t newflag2 = -1;
2972
2973 // Remember the misc. secret flag; if triggered, use this instead
2974
4/4
✓ Branch 0 taken 14182 times.
✓ Branch 1 taken 3198895 times.
✓ Branch 2 taken 4773 times.
✓ Branch 3 taken 9409 times.
3213077 if(layer_scr->sflag[i]>=mfSECRETS01 && layer_scr->sflag[i]<=mfSECRETS16)
2975 9409 msflag=sSECRET01+(layer_scr->sflag[i]-mfSECRETS01);
2976
4/4
✓ Branch 0 taken 126931 times.
✓ Branch 1 taken 3076737 times.
✓ Branch 2 taken 126560 times.
✓ Branch 3 taken 371 times.
3203668 else if(combobuf[layer_scr->data[i]].flag>=mfSECRETS01 && combobuf[layer_scr->data[i]].flag<=mfSECRETS16)
2977 371 msflag=sSECRET01+(combobuf[layer_scr->data[i]].flag-mfSECRETS01);
2978 else
2979 3203297 msflag=0;
2980
2981
2/2
✓ Branch 0 taken 6426154 times.
✓ Branch 1 taken 3213077 times.
9639231 for(int32_t iter=0; iter<2; ++iter)
2982 {
2983 6426154 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
2984
2/2
✓ Branch 0 taken 3213077 times.
✓ Branch 1 taken 3213077 times.
6426154 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
2985
2986 6426154 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2987
2/2
✓ Branch 0 taken 6425676 times.
✓ Branch 1 taken 478 times.
6426154 if (ft != -1) //Change the combos for the secret
2988 {
2989 // Use misc. secret flag instead if one is present
2990
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 2 times.
478 if(msflag!=0)
2991 2 ft=msflag;
2992
2993
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 478 times.
478 if(ft==sSECNEXT)
2994 {
2995 layer_scr->data[i]++;
2996 }
2997 else
2998 {
2999 478 layer_scr->data[i] = layer_scr->secretcombo[ft];
3000 478 layer_scr->cset[i] = layer_scr->secretcset[ft];
3001 }
3002 478 newflag2 = layer_scr->secretflag[ft];
3003 478 int32_t c=layer_scr->data[i];
3004 478 int32_t cs=layer_scr->cset[i];
3005
3006
3/4
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 406 times.
✗ Branch 3 not taken.
478 if (from_active_screen && combobuf[c].type==cSPINTILE1) //Surely this means we can have spin tiles on layers 3+? Isn't that bad? ~Joe123
3007 {
3008 auto [offx, offy] = translate_screen_coordinates_to_world(screen, COMBOX(i), COMBOY(i));
3009 addenemy(screen,offx,offy,(cs<<12)+eSPINTILE1,combobuf[c].o_tile+zc_max(1,combobuf[c].frames));
3010 }
3011 478 }
3012 6426154 }
3013
3014
2/2
✓ Branch 0 taken 478 times.
✓ Branch 1 taken 3212599 times.
3213077 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered secret
3015 3213077 }
3016 2171223 }
3017 3092407 }
3018
3019 18007 word c = scr->numFFC();
3020
2/2
✓ Branch 0 taken 506903 times.
✓ Branch 1 taken 18007 times.
524910 for(word i=0; i<c; i++) //FFC 'trigger flags'
3021 {
3022
3/4
✓ Branch 0 taken 492983 times.
✓ Branch 1 taken 13920 times.
✓ Branch 2 taken 13920 times.
✗ Branch 3 not taken.
506903 if(single>=0) if(i+176!=single) continue;
3023
3024
3/4
✓ Branch 0 taken 166605 times.
✓ Branch 1 taken 326378 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 166605 times.
492983 if((!high16only)||(single>=0))
3025 {
3026 //for (int32_t iter=0; iter<1; ++iter) // Only one kind of FFC flag now.
3027 {
3028 326378 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3029 //No placed flags yet
3030
3031 326378 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
3032
2/2
✓ Branch 0 taken 326347 times.
✓ Branch 1 taken 31 times.
326378 if (ft != -1) //Change the ffc's combo
3033 {
3034
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if(ft==sSECNEXT)
3035 {
3036 zc_ffc_modify(scr->ffcs[i], 1);
3037 }
3038 else
3039 {
3040 31 zc_ffc_set(scr->ffcs[i], scr->secretcombo[ft]);
3041 31 scr->ffcs[i].cset = scr->secretcset[ft];
3042 }
3043 31 }
3044 }
3045 326378 }
3046 492983 }
3047
3048
2/2
✓ Branch 0 taken 15610 times.
✓ Branch 1 taken 2397 times.
18007 if(checktrigger) //Hit all triggers->16-31
3049 {
3050 2397 checktrigger=false;
3051
3052
2/2
✓ Branch 0 taken 2388 times.
✓ Branch 1 taken 9 times.
2397 if(scr->flags6&fTRIGGERF1631)
3053 {
3054 9 int32_t tr = findtrigger(screen); //Normal flags
3055
3056
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 if(tr)
3057 {
3058 5 Z_eventlog("Hit All Triggers->16-31 not fulfilled (%d trigger flag%s remain).\n", tr, tr>1?"s":"");
3059 5 goto endhe;
3060 }
3061 4 }
3062 2392 }
3063
3064
2/2
✓ Branch 0 taken 3168352 times.
✓ Branch 1 taken 18002 times.
3186354 for(int32_t i=0; i<176; i++) // Do the 16-31 secrets
3065 {
3066 //If it's an enemies->secret screen, only do the high 16 if told to
3067 //That way you can have secret and burn/bomb entrance separately
3068 3168352 bool old_enem_secret = get_qr(qr_ENEMIES_SECRET_ONLY_16_31);
3069
6/6
✓ Branch 0 taken 2780624 times.
✓ Branch 1 taken 387728 times.
✓ Branch 2 taken 85184 times.
✓ Branch 3 taken 3083168 times.
✓ Branch 4 taken 19536 times.
✓ Branch 5 taken 65648 times.
3168352 if(((!(old_enem_secret && (scr->flags2&fCLEARSECRET)) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM))
3070 {
3071 3102704 int32_t newflag = -1;
3072
3073
2/2
✓ Branch 0 taken 6205408 times.
✓ Branch 1 taken 3102704 times.
9308112 for(int32_t iter=0; iter<2; ++iter)
3074 {
3075 6205408 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
3076
3077
2/2
✓ Branch 0 taken 3102704 times.
✓ Branch 1 taken 3102704 times.
6205408 if(iter==1) checkflag=scr->sflag[i]; //Placed
3078
3079
4/4
✓ Branch 0 taken 161185 times.
✓ Branch 1 taken 6044223 times.
✓ Branch 2 taken 94853 times.
✓ Branch 3 taken 66332 times.
6205408 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3080 {
3081 66332 rpos_handle_t rpos_handle;
3082
2/2
✓ Branch 0 taken 9952 times.
✓ Branch 1 taken 56380 times.
66332 if (from_active_screen)
3083 {
3084 56380 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
3085 56380 screen_combo_modify_preroutine(rpos_handle);
3086 56380 }
3087
3088 66332 scr->data[i] = scr->secretcombo[checkflag-16+4];
3089 66332 scr->cset[i] = scr->secretcset[checkflag-16+4];
3090 66332 newflag = scr->secretflag[checkflag-16+4];
3091
3092
2/2
✓ Branch 0 taken 9952 times.
✓ Branch 1 taken 56380 times.
66332 if (from_active_screen)
3093 56380 screen_combo_modify_postroutine(rpos_handle);
3094 66332 }
3095 6205408 }
3096
3097
2/2
✓ Branch 0 taken 3036396 times.
✓ Branch 1 taken 66308 times.
3102704 if(newflag >-1) scr->sflag[i] = newflag; //Tiered flag
3098
3099
2/2
✓ Branch 0 taken 18616224 times.
✓ Branch 1 taken 3102704 times.
21718928 for(int32_t j=1; j<=6; j++) //Layers
3100 {
3101 18616224 mapscr* layer_scr = screen_handles[j].scr;
3102
2/2
✓ Branch 0 taken 4895440 times.
✓ Branch 1 taken 13720784 times.
18616224 if (!layer_scr) continue;
3103
3104 4895440 int32_t newflag2 = -1;
3105
3106
2/2
✓ Branch 0 taken 9790880 times.
✓ Branch 1 taken 4895440 times.
14686320 for(int32_t iter=0; iter<2; ++iter)
3107 {
3108 9790880 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
3109
3110
2/2
✓ Branch 0 taken 4895440 times.
✓ Branch 1 taken 4895440 times.
9790880 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
3111
3112
4/4
✓ Branch 0 taken 151246 times.
✓ Branch 1 taken 9639634 times.
✓ Branch 2 taken 131622 times.
✓ Branch 3 taken 19624 times.
9790880 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3113 {
3114 19624 layer_scr->data[i] = layer_scr->secretcombo[checkflag-16+4];
3115 19624 layer_scr->cset[i] = layer_scr->secretcset[checkflag-16+4];
3116 19624 newflag2 = layer_scr->secretflag[checkflag-16+4];
3117 19624 }
3118 9790880 }
3119
3120
2/2
✓ Branch 0 taken 4875816 times.
✓ Branch 1 taken 19624 times.
4895440 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered flag
3121 4895440 }
3122 3102704 }
3123 3168352 }
3124
3125
2/2
✓ Branch 0 taken 506743 times.
✓ Branch 1 taken 18002 times.
524745 for(word i=0; i<c; i++) // FFCs
3126 {
3127
6/6
✓ Branch 0 taken 466852 times.
✓ Branch 1 taken 39891 times.
✓ Branch 2 taken 15367 times.
✓ Branch 3 taken 491376 times.
✓ Branch 4 taken 3530 times.
✓ Branch 5 taken 11837 times.
506743 if((!(scr->flags2&fCLEARSECRET) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM)
3128 {
3129 494906 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3130
3131 //No placed flags yet
3132
4/4
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 494838 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 12 times.
494906 if((checkflag > 15)&&(checkflag < 32)) //If we find a flag, change the combo
3133 {
3134
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (from_active_screen)
3135 9 zc_ffc_set(scr->ffcs[i], scr->secretcombo[checkflag - 16 + 4]);
3136 else
3137 3 scr->ffcs[i].data = scr->secretcombo[checkflag - 16 + 4];
3138 12 scr->ffcs[i].cset = scr->secretcset[checkflag-16+4];
3139 12 }
3140 494906 }
3141 524745 }
3142
3143 endhe:
3144
3145
1/2
✓ Branch 0 taken 18007 times.
✗ Branch 1 not taken.
18007 if (scr->flags4&fDISABLETIME) //Finish timed warp if 'Secrets Disable Timed Warp'
3146 {
3147 if (from_active_screen)
3148 activated_timed_warp = true;
3149 scr->timedwarptics = 0;
3150 }
3151 18007 }
3152
3153 // x,y are world coordinates.
3154 // Returns true if there is a flag (either combo, screen, or ffc) at (x, y).
3155 // Out parameters will be set if the flag is Trigger->Self, which modifies how secrets will be triggered.
3156 13508239 static bool has_flag_trigger(int32_t x, int32_t y, int32_t flag, rpos_t& out_rpos, bool& out_single16)
3157 {
3158
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13508239 times.
13508239 if (!is_in_world_bounds(x, y)) return false;
3159
3160 13508239 bool found_cflag = false;
3161 13508239 bool found_nflag = false;
3162 13508239 bool single16 = false;
3163 13508239 rpos_t rpos = rpos_t::None;
3164
3165
2/2
✓ Branch 0 taken 13506155 times.
✓ Branch 1 taken 94545481 times.
108051636 for (int32_t layer = -1; layer < 6; layer++)
3166 {
3167
2/2
✓ Branch 0 taken 94543397 times.
✓ Branch 1 taken 2084 times.
94545481 if (MAPFLAG2(layer, x, y) == flag)
3168 {
3169 2084 found_nflag = true;
3170 2084 break;
3171 }
3172 94543397 }
3173
3174
2/2
✓ Branch 0 taken 13507935 times.
✓ Branch 1 taken 94556397 times.
108064332 for (int32_t layer = -1; layer < 6; layer++)
3175 {
3176
2/2
✓ Branch 0 taken 94556093 times.
✓ Branch 1 taken 304 times.
94556397 if (MAPCOMBOFLAG2(layer, x, y) == flag)
3177 {
3178 304 found_cflag = true;
3179 304 break;
3180 }
3181 94556093 }
3182
3183
2/2
✓ Branch 0 taken 94557673 times.
✓ Branch 1 taken 13508239 times.
108065912 for (int32_t i=-1; i<6; i++) // Look for Trigger->Self on all layers
3184 {
3185
2/2
✓ Branch 0 taken 94543085 times.
✓ Branch 1 taken 14588 times.
94557673 if (found_nflag) // Trigger->Self (a.k.a Singular) is inherent
3186 {
3187
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 14476 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
14588 if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE) && (MAPFLAG2(i, x, y) == flag))
3188 {
3189 112 rpos = COMBOPOS_REGION(x, y);
3190 112 }
3191
3/4
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 14424 times.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
14476 else if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE16) && (MAPFLAG2(i, x, y) == flag))
3192 {
3193 52 rpos = COMBOPOS_REGION(x, y);
3194 52 single16 = true;
3195 52 }
3196 14588 }
3197
3198
2/2
✓ Branch 0 taken 94555545 times.
✓ Branch 1 taken 2128 times.
94557673 if (found_cflag) // Trigger->Self (a.k.a Singular) is non-inherent
3199 {
3200
3/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 1873 times.
✓ Branch 2 taken 255 times.
✗ Branch 3 not taken.
2128 if ((MAPFLAG2(i, x, y) == mfSINGLE) && (MAPCOMBOFLAG2(i, x, y) == flag))
3201 {
3202 255 rpos = COMBOPOS_REGION(x, y);
3203 255 }
3204
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 1853 times.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
1873 else if ((MAPFLAG2(i, x, y) == mfSINGLE16) && (MAPCOMBOFLAG2(i, x, y) == flag))
3205 {
3206 20 rpos = COMBOPOS_REGION(x, y);
3207 20 single16 = true;
3208 20 }
3209 2128 }
3210 94557673 }
3211
3212 13508239 out_rpos = rpos;
3213 13508239 out_single16 = single16;
3214
4/4
✓ Branch 0 taken 13506155 times.
✓ Branch 1 taken 2084 times.
✓ Branch 2 taken 13505853 times.
✓ Branch 3 taken 302 times.
13508239 return found_nflag || found_cflag || MAPFFCOMBOFLAG(x,y) == flag;
3215 13508239 }
3216
3217 4457867 bool trigger_secrets_if_flag(int32_t x, int32_t y, int32_t flag, bool setflag)
3218 {
3219
8/8
✓ Branch 0 taken 4457627 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 4455730 times.
✓ Branch 3 taken 1897 times.
✓ Branch 4 taken 4455210 times.
✓ Branch 5 taken 520 times.
✓ Branch 6 taken 952 times.
✓ Branch 7 taken 4454258 times.
4457867 if (x < -16 || y < -16 || x >= world_w || y >= world_h) return false;
3220
3221 4454258 mapscr* scr = NULL;
3222 4454258 int32_t screen = -1;
3223 4454258 rpos_t trigger_rpos = rpos_t::None;
3224 4454258 bool single16 = false;
3225
3226 4454258 std::vector<std::pair<int, int>> coords;
3227
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x, y});
3228
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x + 15, y});
3229
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x, y + 15});
3230
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x + 15, y + 15});
3231 4454258 std::vector<rpos_t> rposes_seen;
3232
2/2
✓ Branch 0 taken 4451861 times.
✓ Branch 1 taken 17811750 times.
84483617 for (auto [x, y] : coords)
3233 {
3234
2/4
✓ Branch 0 taken 17811750 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17811750 times.
✗ Branch 3 not taken.
35623500 rpos_t rpos = COMBOPOS_REGION_B(x, y);
3235
2/2
✓ Branch 0 taken 17599367 times.
✓ Branch 1 taken 212383 times.
17811750 if (rpos == rpos_t::None)
3236 212383 continue;
3237
3238
4/6
✓ Branch 0 taken 17599367 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17599367 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 17599356 times.
35198734 if (MAPFFCOMBOFLAG(x, y) == flag)
3239 {
3240
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
22 screen = get_screen_for_world_xy(x, y);
3241 11 break;
3242 }
3243
3244 17599356 bool seen = false;
3245
2/2
✓ Branch 0 taken 13508239 times.
✓ Branch 1 taken 22128287 times.
35636526 for (rpos_t r : rposes_seen)
3246 {
3247
2/2
✓ Branch 0 taken 18037170 times.
✓ Branch 1 taken 4091117 times.
22128287 if (r == rpos)
3248 {
3249 4091117 seen = true;
3250 4091117 break;
3251 }
3252 }
3253
2/2
✓ Branch 0 taken 13508239 times.
✓ Branch 1 taken 4091117 times.
17599356 if (seen)
3254 4091117 continue;
3255
3256
1/2
✓ Branch 0 taken 13508239 times.
✗ Branch 1 not taken.
13508239 rposes_seen.push_back(rpos);
3257
4/6
✓ Branch 0 taken 13508239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13508239 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2386 times.
✓ Branch 5 taken 13505853 times.
27016478 if (has_flag_trigger(x, y, flag, trigger_rpos, single16))
3258 {
3259
2/4
✓ Branch 0 taken 2386 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2386 times.
✗ Branch 3 not taken.
4772 screen = get_screen_for_world_xy(x, y);
3260 2386 break;
3261 }
3262 }
3263
3264
3/4
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 4451861 times.
✓ Branch 2 taken 2397 times.
✗ Branch 3 not taken.
4454258 if (screen != -1) scr = get_scr(screen);
3265
2/2
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 4451861 times.
4454258 if (!scr) return false;
3266
3267
2/2
✓ Branch 0 taken 1958 times.
✓ Branch 1 taken 439 times.
2397 if (trigger_rpos == rpos_t::None)
3268 {
3269 1958 checktrigger = true;
3270
1/2
✓ Branch 0 taken 1958 times.
✗ Branch 1 not taken.
1958 trigger_secrets_for_screen(TriggerSource::Unspecified, screen);
3271 1958 }
3272 else
3273 {
3274 439 checktrigger = true;
3275
2/4
✓ Branch 0 taken 439 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 439 times.
✗ Branch 3 not taken.
439 trigger_secrets_for_screen(TriggerSource::Singular, scr, single16, RPOS_TO_POS(trigger_rpos));
3276 }
3277
3278
1/2
✓ Branch 0 taken 2397 times.
✗ Branch 1 not taken.
2397 sfx(scr->secretsfx);
3279
3280
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2391 times.
2397 if(scr->flags6&fTRIGGERFPERM)
3281 {
3282
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 int32_t flags_remaining = findtrigger(screen); //Normal flags
3283
3284
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (flags_remaining)
3285 {
3286
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 Z_eventlog("Hit All Triggers->Perm Secret not fulfilled (%d trigger flag%s remain).\n", flags_remaining, flags_remaining>1?"s":"");
3287 3 setflag=false;
3288 3 }
3289
3290 // Only actually trigger secrets now if 1) all triggers are gone and 2) QR qr_ALLTRIG_PERMSEC_NO_TEMP is off, in
3291 // which case only the screen state for mSECRET may be set below.
3292
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
6 if (!flags_remaining && !get_qr(qr_ALLTRIG_PERMSEC_NO_TEMP))
3293 {
3294 trigger_secrets_for_screen(TriggerSource::Unspecified, scr, scr->flags6&fTRIGGERF1631, -1);
3295 }
3296 6 }
3297
3298
5/6
✓ Branch 0 taken 2292 times.
✓ Branch 1 taken 105 times.
✓ Branch 2 taken 2292 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1108 times.
✓ Branch 5 taken 1184 times.
2397 if (setflag && canPermSecret(cur_dmap, screen))
3299
2/2
✓ Branch 0 taken 721 times.
✓ Branch 1 taken 463 times.
1905 if(!(scr->flags5&fTEMPSECRETS))
3300
1/2
✓ Branch 0 taken 721 times.
✗ Branch 1 not taken.
721 setmapflag(scr, mSECRET);
3301
3302 2397 return true;
3303 4457867 }
3304
3305 14809012 void update_slopes()
3306 {
3307
2/2
✓ Branch 0 taken 142356 times.
✓ Branch 1 taken 14809012 times.
14951368 for (auto& p : slopes)
3308 {
3309 142356 slope_object& s = p.second;
3310 142356 s.updateslope(); //sets old x/y poses
3311 }
3312 14809012 }
3313
3314 14402369 void update_freeform_combos()
3315 {
3316 14402369 ffscript_engine(false);
3317
2/2
✓ Branch 0 taken 24172 times.
✓ Branch 1 taken 14378197 times.
14402369 if ( !FFCore.system_suspend[susptUPDATEFFC] )
3318 {
3319 14378197 int wrap_right = world_w + 32;
3320 14378197 int wrap_bottom = world_h + 32;
3321
3322 485520731 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
3323 471142534 mapscr* scr = ffc_handle.scr;
3324 471142534 ffcdata& thisffc = *ffc_handle.ffc;
3325
3326 // Combo 0?
3327
2/2
✓ Branch 0 taken 44992239 times.
✓ Branch 1 taken 426150295 times.
471142534 if(thisffc.data==0)
3328 426150295 return;
3329
3330 // Changer?
3331
2/2
✓ Branch 0 taken 543029 times.
✓ Branch 1 taken 44449210 times.
44992239 if(thisffc.flags&ffc_changer)
3332 543029 return;
3333
3334 // Stationary?
3335
2/2
✓ Branch 0 taken 9844 times.
✓ Branch 1 taken 44439366 times.
44449210 if(thisffc.flags&ffc_stationary)
3336 9844 return;
3337
3338 // Frozen because Hero's holding up an item?
3339
3/4
✓ Branch 0 taken 138282 times.
✓ Branch 1 taken 44301084 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 138282 times.
44439366 if(Hero.getHoldClk()>0 && (thisffc.flags&ffc_ignoreholdup)==0)
3340 138282 return;
3341
3342 // Check for changers
3343
2/2
✓ Branch 0 taken 29543786 times.
✓ Branch 1 taken 14757298 times.
44301084 if (thisffc.link==0)
3344 {
3345 442453159 for_some_ffcs([&](const ffc_handle_t& other_ffc_handle) {
3346
2/2
✓ Branch 0 taken 14755762 times.
✓ Branch 1 taken 412940099 times.
427695861 if (ffc_handle.id == other_ffc_handle.id)
3347 14755762 return true;
3348
3349 412940099 ffcdata& otherffc = *other_ffc_handle.ffc;
3350 // Combo 0?
3351
2/2
✓ Branch 0 taken 144689583 times.
✓ Branch 1 taken 268250516 times.
412940099 if(otherffc.data==0)
3352 268250516 return true;
3353
3354 // Not a changer?
3355
2/2
✓ Branch 0 taken 140701406 times.
✓ Branch 1 taken 3988177 times.
144689583 if(!(otherffc.flags&ffc_changer))
3356 140701406 return true;
3357
3358 // Ignore this changer?
3359
4/4
✓ Branch 0 taken 546579 times.
✓ Branch 1 taken 3441598 times.
✓ Branch 2 taken 299257 times.
✓ Branch 3 taken 3142341 times.
3988177 if((otherffc.x.getInt()==thisffc.changer_x&&otherffc.y.getInt()==thisffc.changer_y) || thisffc.flags&ffc_ignorechanger)
3360 845836 return true;
3361
3362
3/4
✓ Branch 0 taken 2721043 times.
✓ Branch 1 taken 421298 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3562 times.
3145903 if((isonline(thisffc.x.getZLong(), thisffc.y.getZLong(), thisffc.prev_changer_x, thisffc.prev_changer_y, otherffc.x.getZLong(), otherffc.y.getZLong()) || // Along the line, or...
3363 ( // At exactly the same position,
3364
2/2
✓ Branch 0 taken 208792 times.
✓ Branch 1 taken 2512251 times.
2721043 (thisffc.x==otherffc.x && thisffc.y==otherffc.y))
3365
2/2
✓ Branch 0 taken 2303459 times.
✓ Branch 1 taken 2512251 times.
208792 ||
3366 //or imprecision and close enough
3367
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
5024502 ( (thisffc.flags&ffc_imprecisionchanger) && ((abs(thisffc.x.getZLong() - otherffc.x.getZLong()) < 10000) && abs(thisffc.y.getZLong() - otherffc.y.getZLong()) < 10000) )
3368 )
3369 && //and...
3370
2/2
✓ Branch 0 taken 3562 times.
✓ Branch 1 taken 2721195 times.
2724757 (thisffc.prev_changer_x>-10000000 && thisffc.prev_changer_y>-10000000)) // This isn't the first frame on this screen
3371 {
3372 3562 zc_ffc_changer(thisffc, otherffc, ffc_handle.id, other_ffc_handle.id);
3373 3562 return false;
3374 }
3375
3376 2721195 return true;
3377 426679763 });
3378 14757298 }
3379
3380
2/2
✓ Branch 0 taken 29543786 times.
✓ Branch 1 taken 14757298 times.
44301084 ffcdata* linked_ffc = thisffc.link ? get_ffc_handle(thisffc.link - 1).ffc : nullptr;
3381
4/4
✓ Branch 0 taken 14757298 times.
✓ Branch 1 taken 29543786 times.
✓ Branch 2 taken 14680008 times.
✓ Branch 3 taken 14863778 times.
44301084 if (linked_ffc ? !linked_ffc->delay : !thisffc.delay)
3382 {
3383
4/4
✓ Branch 0 taken 182609 times.
✓ Branch 1 taken 14681169 times.
✓ Branch 2 taken 85331 times.
✓ Branch 3 taken 97278 times.
14863778 if(thisffc.link && (thisffc.link-1) != ffc_handle.id)
3384 {
3385 97278 thisffc.prev_changer_x = thisffc.x.getZLong();
3386 97278 thisffc.prev_changer_y = thisffc.y.getZLong();
3387 97278 thisffc.x += linked_ffc->vx;
3388 97278 thisffc.y += linked_ffc->vy;
3389 97278 }
3390 else
3391 {
3392 14766500 thisffc.prev_changer_x = thisffc.x.getZLong();
3393 14766500 thisffc.prev_changer_y = thisffc.y.getZLong();
3394 14766500 thisffc.x += thisffc.vx;
3395 14766500 thisffc.y += thisffc.vy;
3396 14766500 thisffc.vx += thisffc.ax;
3397 14766500 thisffc.vy += thisffc.ay;
3398
3399
3400
2/2
✓ Branch 0 taken 444046 times.
✓ Branch 1 taken 14322454 times.
14766500 if(get_qr(qr_OLD_FFC_SPEED_CAP))
3401 {
3402
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx>128) thisffc.vx=128;
3403
3404
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx<-128) thisffc.vx=-128;
3405
3406
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy>128) thisffc.vy=128;
3407
3408
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy<-128) thisffc.vy=-128;
3409 14322454 }
3410 }
3411 14863778 }
3412 else
3413 {
3414
3/4
✓ Branch 0 taken 1161 times.
✓ Branch 1 taken 76129 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1161 times.
29437306 if(!thisffc.link || (thisffc.link-1) == ffc_handle.id)
3415 76129 thisffc.delay--;
3416 }
3417
3418 // Check if the FFC's off the side of the screen
3419
3420 // Left
3421
2/2
✓ Branch 0 taken 10449 times.
✓ Branch 1 taken 14930619 times.
14941068 if(thisffc.x<-32)
3422 {
3423
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 10196 times.
10449 if(scr->flags6&fWRAPAROUNDFF)
3424 {
3425 253 thisffc.x = wrap_right+(thisffc.x+32);
3426 253 thisffc.solid_update(false);
3427 253 thisffc.prev_changer_y = thisffc.y.getZLong();
3428 // Re-enable previous changer
3429 253 thisffc.changer_x = -1000;
3430 253 thisffc.changer_y = -1000;
3431 253 }
3432
2/2
✓ Branch 0 taken 10127 times.
✓ Branch 1 taken 69 times.
10196 else if(thisffc.x<-64)
3433 {
3434 69 zc_ffc_set(thisffc, 0);
3435 69 thisffc.flags&=~ffc_carryover;
3436 69 }
3437 10449 }
3438 // Right
3439
2/2
✓ Branch 0 taken 14930438 times.
✓ Branch 1 taken 181 times.
14930619 else if(thisffc.x>=wrap_right)
3440 {
3441
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 53 times.
181 if(scr->flags6&fWRAPAROUNDFF)
3442 {
3443 128 thisffc.x = thisffc.x-wrap_right-32;
3444 128 thisffc.solid_update(false);
3445 128 thisffc.prev_changer_y = thisffc.y.getZLong();
3446 128 thisffc.changer_x = -1000;
3447 128 thisffc.changer_y = -1000;
3448 128 }
3449 else
3450 {
3451 53 zc_ffc_set(thisffc, 0);
3452 53 thisffc.flags&=~ffc_carryover;
3453 }
3454 181 }
3455
3456 // Top
3457
2/2
✓ Branch 0 taken 25480 times.
✓ Branch 1 taken 14915588 times.
14941068 if(thisffc.y<-32)
3458 {
3459
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 25472 times.
25480 if(scr->flags6&fWRAPAROUNDFF)
3460 {
3461 8 thisffc.y = wrap_bottom+(thisffc.y+32);
3462 8 thisffc.solid_update(false);
3463 8 thisffc.prev_changer_x = thisffc.x.getZLong();
3464 8 thisffc.changer_x = -1000;
3465 8 thisffc.changer_y = -1000;
3466 8 }
3467
2/2
✓ Branch 0 taken 25155 times.
✓ Branch 1 taken 317 times.
25472 else if(thisffc.y<-64)
3468 {
3469 317 zc_ffc_set(thisffc, 0);
3470 317 thisffc.flags&=~ffc_carryover;
3471 317 }
3472 25480 }
3473 // Bottom
3474
2/2
✓ Branch 0 taken 14914744 times.
✓ Branch 1 taken 844 times.
14915588 else if(thisffc.y>=wrap_bottom)
3475 {
3476
2/2
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 91 times.
844 if(scr->flags6&fWRAPAROUNDFF)
3477 {
3478 753 thisffc.y = thisffc.y-wrap_bottom-32;
3479 753 thisffc.solid_update(false);
3480 753 thisffc.prev_changer_y = thisffc.x.getZLong();
3481 753 thisffc.changer_x = -1000;
3482 753 thisffc.changer_y = -1000;
3483 753 }
3484 else
3485 {
3486 91 zc_ffc_set(thisffc, 0);
3487 91 thisffc.flags&=~ffc_carryover;
3488 }
3489 844 }
3490 14941068 thisffc.solid_update();
3491 441782518 });
3492 14378197 }
3493 14402369 }
3494
3495 bool hitflag(int32_t x, int32_t y, int32_t flagtype, byte layers)
3496 {
3497 for(int q = 0; q < 7; ++q)
3498 {
3499 if(layers&(1<<q)) //if layer is to be checked
3500 if(MAPFLAG2(q-1,x,y)==flagtype||MAPCOMBOFLAG2(q-1,x,y)==flagtype) //matching flag
3501 return true;
3502 }
3503 return false;
3504 }
3505
3506 231 optional<int> nextscr(int screen, int dir)
3507 {
3508 231 auto [m, s] = nextscr2(cur_map, screen, dir);
3509
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231 times.
231 if (m == -1) return nullopt;
3510 462 return (m<<7) + s;
3511 231 }
3512
3513 1058 std::pair<int32_t, int32_t> nextscr2(int32_t dir)
3514 {
3515 1058 int32_t map = cur_map;
3516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1058 times.
1058 int32_t screen = screenscrolling ? scrolling_hero_screen : Hero.current_screen;
3517 1058 return nextscr2(map, screen, dir);
3518 }
3519
3520 5576 std::pair<int32_t, int32_t> nextscr2(int map, int screen, int32_t dir)
3521 {
3522 5576 screen = screen_index_direction(screen, (direction)dir);
3523
3524 // need to check for screens on other maps, 's' not valid, etc.
3525 5576 int32_t index = (hero_scr->sidewarpindex >> (dir*2))&3;
3526
3527 // Fun fact: when a scrolling warp is triggered, this function
3528 // is never even called! - Saf
3529
2/2
✓ Branch 0 taken 3326 times.
✓ Branch 1 taken 2250 times.
6120 if(hero_scr->sidewarptype[index] == 3) // scrolling warp
3530 {
3531
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 482 times.
✓ Branch 2 taken 525 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 697 times.
2250 switch(dir)
3532 {
3533 case up:
3534
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 399 times.
482 if(!(hero_scr->flags2&wfUP)) goto nowarp;
3535
3536 83 break;
3537
3538 case down:
3539
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 446 times.
525 if(!(hero_scr->flags2&wfDOWN)) goto nowarp;
3540
3541 79 break;
3542
3543 case left:
3544
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 337 times.
546 if(!(hero_scr->flags2&wfLEFT)) goto nowarp;
3545
3546 209 break;
3547
3548 case right:
3549
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 524 times.
697 if(!(hero_scr->flags2&wfRIGHT)) goto nowarp;
3550
3551 173 break;
3552 }
3553
3554 544 map = DMaps[hero_scr->sidewarpdmap[index]].map;
3555 544 screen = hero_scr->sidewarpscr[index] + DMaps[hero_scr->sidewarpdmap[index]].xoff;
3556 544 }
3557
3558 nowarp:
3559
4/4
✓ Branch 0 taken 5512 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 5400 times.
5576 if(screen<0||screen>=128)
3560 176 return {-1, -1};
3561
3562 5400 return {map, screen};
3563 5576 }
3564
3565 403 optional<int> nextscr_mi(int mi, int dir)
3566 {
3567 403 int map = mi/MAPSCRSNORMAL;
3568 403 int screen = mi%MAPSCRSNORMAL;
3569 403 auto [m, s] = nextscr2(map, screen, dir);
3570
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 402 times.
403 if (m == -1) return nullopt;
3571 804 return (m<<7) + s;
3572 403 }
3573
3574 2114 void bombdoor(int32_t x,int32_t y)
3575 {
3576
2/2
✓ Branch 0 taken 2094 times.
✓ Branch 1 taken 20 times.
2114 if (!is_in_world_bounds(x, y))
3577 20 return;
3578
3579 2094 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
3580 2094 mapscr* scr = rpos_handle.scr;
3581 2094 int screen = scr->screen;
3582 2902 auto [x0, y0] = translate_screen_coordinates_to_world(rpos_handle.screen);
3583 #define CHECK_RECT(x,y,rx1,ry1,rx2,ry2) (isinRect(x,y,x0+rx1,y0+ry1,x0+rx2,y0+ry2))
3584
3585
12/12
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 2015 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 69 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 69 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 69 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 69 times.
2094 if(scr->door[0]==dBOMB && CHECK_RECT(x,y,100,0,139,48))
3586 {
3587 69 scr->door[0]=dBOMBED;
3588 69 putdoor(scr, scrollbuf, 0, dBOMBED);
3589 69 setmapflag(scr, mDOOR_UP);
3590 69 markBmap(-1, screen);
3591
3592
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
69 if(auto v = nextscr(screen, up))
3593 {
3594 69 setmapflag_mi(*v, mDOOR_DOWN);
3595 69 markBmap(-1,*v-(get_currdmap()<<7));
3596 69 }
3597 69 }
3598
3599
12/12
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2045 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 39 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 39 times.
2094 if(scr->door[1]==dBOMB && CHECK_RECT(x,y,100,112,139,176))
3600 {
3601 39 scr->door[1]=dBOMBED;
3602 39 putdoor(scr, scrollbuf, 1, dBOMBED);
3603 39 setmapflag(scr, mDOOR_DOWN);
3604 39 markBmap(-1, rpos_handle.screen);
3605
3606
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if(auto v = nextscr(rpos_handle.screen, down))
3607 {
3608 39 setmapflag_mi(*v, mDOOR_UP);
3609 39 markBmap(-1,*v-(get_currdmap()<<7));
3610 39 }
3611 39 }
3612
3613
12/12
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 2027 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 51 times.
✓ Branch 8 taken 16 times.
✓ Branch 9 taken 51 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 51 times.
2094 if(scr->door[2]==dBOMB && CHECK_RECT(x,y,0,60,48,98))
3614 {
3615 51 scr->door[2]=dBOMBED;
3616 51 putdoor(scr, scrollbuf, 2, dBOMBED);
3617 51 setmapflag(scr, mDOOR_LEFT);
3618 51 markBmap(-1, rpos_handle.screen);
3619
3620
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto v = nextscr(rpos_handle.screen, left))
3621 {
3622 51 setmapflag_mi(*v, mDOOR_RIGHT);
3623 51 markBmap(-1,*v-(get_currdmap()<<7));
3624 51 }
3625 51 }
3626
3627
12/12
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 2008 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 72 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 72 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 72 times.
✓ Branch 10 taken 14 times.
✓ Branch 11 taken 72 times.
2094 if(scr->door[3]==dBOMB && CHECK_RECT(x,y,192,60,240,98))
3628 {
3629 72 scr->door[3]=dBOMBED;
3630 72 putdoor(scr, scrollbuf, 3, dBOMBED);
3631 72 setmapflag(scr, mDOOR_RIGHT);
3632 72 markBmap(-1, rpos_handle.screen);
3633
3634
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if(auto v = nextscr(rpos_handle.screen, right))
3635 {
3636 72 setmapflag_mi(*v, mDOOR_LEFT);
3637 72 markBmap(-1,*v-(get_currdmap()<<7));
3638 72 }
3639 72 }
3640 2114 }
3641
3642 6515227114 void draw_cmb(BITMAP* dest, int32_t x, int32_t y, int32_t cid, int32_t cset,
3643 bool over, bool transp)
3644 {
3645 6515227114 auto& cmb = combobuf[cid];
3646
2/2
✓ Branch 0 taken 90743 times.
✓ Branch 1 taken 6515136371 times.
6515227114 if(cmb.animflags & AF_EDITOR_ONLY)
3647 90743 return;
3648
2/2
✓ Branch 0 taken 3440275441 times.
✓ Branch 1 taken 3074860930 times.
6515136371 if(over)
3649 {
3650
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3440275441 times.
3440275441 if(cmb.animflags & AF_TRANSPARENT)
3651 transp = !transp;
3652
2/2
✓ Branch 0 taken 319148412 times.
✓ Branch 1 taken 3121127029 times.
3440275441 if(transp)
3653 319148412 overcombotranslucent(dest, x, y, cid, cset, 128);
3654 3121127029 else overcombo(dest, x, y, cid, cset);
3655 3440275441 }
3656 3074860930 else putcombo(dest, x, y, cid, cset);
3657 6515227114 }
3658 6515235562 void draw_cmb_pos(BITMAP* dest, int32_t x, int32_t y, rpos_t rpos, int32_t cid,
3659 int32_t cset, byte layer, bool over, bool transp)
3660 {
3661
2/2
✓ Branch 0 taken 755578275 times.
✓ Branch 1 taken 5759657287 times.
6515235562 if (rpos != rpos_t::None)
3662 {
3663 5759657287 rpos_t plrpos = COMBOPOS_REGION_B(Hero.x+8, Hero.y+8);
3664
2/2
✓ Branch 0 taken 749524 times.
✓ Branch 1 taken 5758907763 times.
5759657287 if (plrpos != rpos_t::None)
3665 {
3666 5758907763 bool dosw = false;
3667
4/4
✓ Branch 0 taken 67632 times.
✓ Branch 1 taken 5758840131 times.
✓ Branch 2 taken 59184 times.
✓ Branch 3 taken 8448 times.
5758907763 if (rpos == hooked_comborpos && (hooked_layerbits & (1<<layer)))
3668 {
3669
1/2
✓ Branch 0 taken 8448 times.
✗ Branch 1 not taken.
8448 if(hooked_undercombos[layer] > -1)
3670 {
3671 draw_cmb(dest, x, y,
3672 hooked_undercombos[layer], hooked_undercombos[layer+7], over, transp);
3673 }
3674 8448 dosw = true;
3675 8448 }
3676
4/4
✓ Branch 0 taken 32690133 times.
✓ Branch 1 taken 5726209182 times.
✓ Branch 2 taken 8448 times.
✓ Branch 3 taken 32681685 times.
5758899315 else if (rpos == plrpos && (hooked_layerbits & (1<<(layer+8))))
3677 {
3678 8448 dosw = true;
3679 8448 }
3680
2/2
✓ Branch 0 taken 5758890867 times.
✓ Branch 1 taken 16896 times.
5758907763 if (dosw)
3681 {
3682
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 16896 times.
✗ Branch 3 not taken.
16896 switch (Hero.switchhookstyle)
3683 {
3684 default: case swPOOF:
3685 break; //Nothing special here
3686 case swFLICKER:
3687 {
3688
2/2
✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 8448 times.
16896 if(abs(Hero.switchhookclk-33)&0b1000)
3689 8448 break; //Drawn this frame
3690 8448 return; //Not drawn this frame
3691 }
3692 case swRISE:
3693 {
3694 //Draw rising up
3695 y -= 8-(abs(Hero.switchhookclk-32)/4);
3696 break;
3697 }
3698 }
3699 8448 }
3700 5758899315 }
3701 5759648839 }
3702
3703 6515227114 draw_cmb(dest, x, y, cid, cset, over, transp);
3704 6515235562 }
3705
3706 // `draw_cmb_pos` only does meaningful work if the combo being drawn is within the bounds of
3707 // the `bmp` bitmap. However, even getting to the point where `puttile16` (for example) knows
3708 // to cull is somewhat expensive. Since it can only draw 16x16 pixels, we can do the equivalent
3709 // culling here by determining the rows/columns that are within the bitmap bounds. This nets
3710 // on the order of ~30 FPS in uncapped mode on my machine, depending on the viewport/region size.
3711 //
3712 // These two inequalities must be true for `draw_cmb_pos` to do anything useful:
3713 //
3714 // -16 < comboPositionX*16 + x < bitmapWidth
3715 // -16 < comboPositionY*16 + y < bitmapHeight
3716 //
3717 // The following start/end values are derived directly from the above.
3718 //
3719 // `x` and `y` are the offsets the combos will be drawn into the bitmap.
3720 40246811 static void get_bounds_for_draw_cmb_calls(BITMAP* bmp, int x, int y, int& start_x, int& end_x, int& start_y, int& end_y)
3721 {
3722 // if (bmp->clip)
3723 // {
3724 // start_x = MAX(0, ceil((bmp->cl - 15 - x) / 16.0));
3725 // end_x = MIN(16, ceil((bmp->cr - x) / 16.0));
3726 // start_y = MAX(0, ceil((bmp->ct - 15 - y) / 16.0));
3727 // end_y = MIN(11, ceil((bmp->cb - y) / 16.0));
3728 // return;
3729 // }
3730
3731
2/2
✓ Branch 0 taken 2181084 times.
✓ Branch 1 taken 38065727 times.
40246811 start_x = MAX(0, ceil((-15 - x) / 16.0));
3732
2/2
✓ Branch 0 taken 2189800 times.
✓ Branch 1 taken 38057011 times.
40246811 end_x = MIN(16, ceil((bmp->w - x) / 16.0));
3733
2/2
✓ Branch 0 taken 38851468 times.
✓ Branch 1 taken 1395343 times.
40246811 start_y = MAX(0, ceil((-15 - y) / 16.0));
3734
2/2
✓ Branch 0 taken 1687374 times.
✓ Branch 1 taken 38559437 times.
40246811 end_y = MIN(11, ceil((bmp->h - y) / 16.0));
3735 40246811 }
3736
3737 186960519 void do_ffc_layer(BITMAP* bmp, int32_t layer, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3738 {
3739
1/2
✓ Branch 0 taken 186960519 times.
✗ Branch 1 not taken.
186960519 if(!show_ffcs) return;
3740 186960519 mapscr* scr = screen_handle.scr;
3741 186960519 mapscr* base_scr = screen_handle.base_scr;
3742
3743 186960519 y += playing_field_offset;
3744
3745 186960519 bool is_bg_layer = layer < -1;
3746
2/2
✓ Branch 0 taken 33926573 times.
✓ Branch 1 taken 153033946 times.
186960519 int real_layer = is_bg_layer ? abs(layer) : layer;
3747
2/2
✓ Branch 0 taken 186960519 times.
✓ Branch 1 taken 5581189773 times.
5768150292 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3748 {
3749
2/2
✓ Branch 0 taken 5375692187 times.
✓ Branch 1 taken 205497586 times.
5581189773 if (base_scr->ffcs[i].data == 0)
3750 5375692187 continue;
3751
4/4
✓ Branch 0 taken 37360942 times.
✓ Branch 1 taken 168136644 times.
✓ Branch 2 taken 18682952 times.
✓ Branch 3 taken 18677990 times.
205497586 if(real_layer == 2 && (is_bg_layer != XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG)))
3752 18677990 continue;
3753
4/4
✓ Branch 0 taken 37360942 times.
✓ Branch 1 taken 149458654 times.
✓ Branch 2 taken 18682952 times.
✓ Branch 3 taken 18677990 times.
186819596 else if (real_layer == 3 && (is_bg_layer != XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)))
3754 18677990 continue;
3755
4/4
✓ Branch 0 taken 149463616 times.
✓ Branch 1 taken 18677990 times.
✓ Branch 2 taken 18682952 times.
✓ Branch 3 taken 130780664 times.
168141606 if (real_layer > -1 && base_scr->ffcs[i].layer != real_layer)
3756 130780664 continue;
3757
3758
6/6
✓ Branch 0 taken 3008970 times.
✓ Branch 1 taken 34351972 times.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 3003860 times.
✓ Branch 4 taken 2626 times.
✓ Branch 5 taken 2484 times.
37360942 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3759 2484 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3760
3761 37358458 base_scr->ffcs[i].draw_ffc(bmp, x, y, (layer==-1));
3762 37358458 }
3763 186960519 }
3764 170937415 void _do_current_ffc_layer(BITMAP* bmp, int32_t layer)
3765 {
3766
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 170937415 times.
170937415 if(!show_ffcs) return;
3767 346453052 for_every_base_screen_in_region([&](mapscr* base_scr, unsigned int region_scr_x, unsigned int region_scr_y) {
3768 175515637 screen_handle_t handle = {base_scr, base_scr, base_scr->screen, 0};
3769 175515637 do_ffc_layer(bmp, layer, handle, 0, 0);
3770 175515637 });
3771 170937415 }
3772 76513165 void do_scrolling_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3773 {
3774 76513165 mapscr* scr = screen_handle.scr;
3775 76513165 mapscr* base_scr = screen_handle.base_scr;
3776
3777
4/4
✓ Branch 0 taken 61847497 times.
✓ Branch 1 taken 14665668 times.
✓ Branch 2 taken 14665668 times.
✓ Branch 3 taken 76513165 times.
76513165 if (type == -3 || type == -4)
3778 {
3779 29331336 y += playing_field_offset;
3780
3781
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
29331336 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3782 {
3783 if (base_scr->ffcs[i].data == 0)
3784 continue;
3785
3786 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3787 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3788
3789 base_scr->ffcs[i].draw_ffc(bmp, x, y, (type==-4));
3790 }
3791 return;
3792 }
3793
3794 76513165 x -= viewport.x;
3795 76513165 y -= viewport.y - playing_field_offset;
3796
3797 76513165 bool over = true, transp = false;
3798 76513165 int layer = screen_handle.layer;
3799
3800
7/8
✓ Branch 0 taken 55282405 times.
✓ Branch 1 taken 21230760 times.
✓ Branch 2 taken 13416642 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 34185791 times.
✓ Branch 5 taken 21096614 times.
✓ Branch 6 taken 3175019 times.
✓ Branch 7 taken 4639099 times.
76513165 switch(type ? type : layer)
3801 {
3802 case -2: //push blocks
3803
2/2
✓ Branch 0 taken 19520123 times.
✓ Branch 1 taken 14665668 times.
34185791 if (scr)
3804 {
3805
2/2
✓ Branch 0 taken 3435541648 times.
✓ Branch 1 taken 23710427 times.
3435035785 for(int32_t i=0; i<176; i++)
3806 {
3807 3435541648 int32_t mf=scr->sflag[i], mf2 = combobuf[scr->data[i]].flag;
3808
3809
10/10
✓ Branch 0 taken 3435371304 times.
✓ Branch 1 taken 170344 times.
✓ Branch 2 taken 3433899332 times.
✓ Branch 3 taken 1471972 times.
✓ Branch 4 taken 3433270349 times.
✓ Branch 5 taken 628983 times.
✓ Branch 6 taken 24420859 times.
✓ Branch 7 taken 3408849490 times.
✓ Branch 8 taken 42762999 times.
✓ Branch 9 taken 16705821 times.
3472589116 if(mf==mfPUSHUD || mf==mfPUSH4 || mf==mfPUSHED || ((mf>=mfPUSHLR)&&(mf<=mfPUSHRINS))
3810
6/8
✓ Branch 0 taken 3430388820 times.
✓ Branch 1 taken 21539330 times.
✓ Branch 2 taken 3430388820 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3430388820 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 37047468 times.
✓ Branch 7 taken 3393341352 times.
3433270349 || mf2==mfPUSHUD || mf2==mfPUSH4 || mf2==mfPUSHED || ((mf2>=mfPUSHLR)&&(mf2<=mfPUSHRINS)))
3811 {
3812
4/4
✓ Branch 0 taken 4772507 times.
✓ Branch 1 taken 695982 times.
✓ Branch 2 taken 3657 times.
✓ Branch 3 taken 4768850 times.
90994487 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3813 5468489 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3814 5468489 }
3815 3415515662 }
3816 23710427 }
3817 38376095 return;
3818
3819 case -1: //over combo
3820
1/2
✓ Branch 0 taken 21096614 times.
✗ Branch 1 not taken.
21096614 if (scr)
3821 {
3822
2/2
✓ Branch 0 taken 3713004064 times.
✓ Branch 1 taken 21096614 times.
3734100678 for(int32_t i=0; i<176; i++)
3823 {
3824
2/2
✓ Branch 0 taken 3693728008 times.
✓ Branch 1 taken 19276056 times.
3713004064 if(combo_class_buf[combobuf[scr->data[i]].type].overhead)
3825 {
3826
4/4
✓ Branch 0 taken 15523213 times.
✓ Branch 1 taken 3752843 times.
✓ Branch 2 taken 22320 times.
✓ Branch 3 taken 15500893 times.
19276056 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3827 19276056 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3828 19276056 }
3829 3713004064 }
3830 21096614 }
3831 21096614 return;
3832
3833 case 1:
3834 case 4:
3835 case 5:
3836 case 6:
3837
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13416642 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
13416642 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3838 {
3839
1/2
✓ Branch 0 taken 13416642 times.
✗ Branch 1 not taken.
13416642 if (scr)
3840 {
3841
2/2
✓ Branch 0 taken 11757431 times.
✓ Branch 1 taken 1659211 times.
13416642 if(base_scr->layeropacity[layer-1]!=255)
3842 1659211 transp = true;
3843 13416642 break;
3844 }
3845 }
3846 return;
3847
3848 case 2:
3849
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3175019 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3175019 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3850 {
3851
1/2
✓ Branch 0 taken 3175019 times.
✗ Branch 1 not taken.
3175019 if (scr)
3852 {
3853
2/2
✓ Branch 0 taken 2955422 times.
✓ Branch 1 taken 219597 times.
3175019 if(base_scr->layeropacity[layer-1]!=255)
3854 219597 transp = true;
3855
3856
2/2
✓ Branch 0 taken 3046110 times.
✓ Branch 1 taken 128909 times.
3175019 if(XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3857 128909 over = false;
3858
3859 3175019 break;
3860 }
3861 }
3862 return;
3863
3864 case 3:
3865
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4639099 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4639099 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3866 {
3867
1/2
✓ Branch 0 taken 4639099 times.
✗ Branch 1 not taken.
4639099 if (scr)
3868 {
3869
2/2
✓ Branch 0 taken 4565386 times.
✓ Branch 1 taken 73713 times.
4639099 if(base_scr->layeropacity[layer-1]!=255)
3870 73713 transp = true;
3871
3872
2/2
✓ Branch 0 taken 36654 times.
✓ Branch 1 taken 60483 times.
4639099 if(XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
3873
2/2
✓ Branch 0 taken 97137 times.
✓ Branch 1 taken 4541962 times.
4639099 && !XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3874 60483 over = false;
3875
3876 4639099 break;
3877 }
3878 }
3879 return;
3880 }
3881
3882 int start_x, end_x, start_y, end_y;
3883 21230760 get_bounds_for_draw_cmb_calls(bmp, x, y, start_x, end_x, start_y, end_y);
3884
2/2
✓ Branch 0 taken 21230760 times.
✓ Branch 1 taken 225310835 times.
246541595 for (int cy = start_y; cy < end_y; cy++)
3885 {
3886
2/2
✓ Branch 0 taken 3414656055 times.
✓ Branch 1 taken 225310835 times.
3639966890 for (int cx = start_x; cx < end_x; cx++)
3887 {
3888 3414656055 int i = cx + cy*16;
3889
4/4
✓ Branch 0 taken 3031502604 times.
✓ Branch 1 taken 383153451 times.
✓ Branch 2 taken 10099056 times.
✓ Branch 3 taken 3021403548 times.
3414656055 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3890 3414656055 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, over, transp);
3891 3414656055 }
3892 225310835 }
3893 61847497 }
3894
3895 269002203 bool lenscheck(mapscr* scr, int layer)
3896 {
3897
4/4
✓ Branch 0 taken 268823255 times.
✓ Branch 1 taken 178948 times.
✓ Branch 2 taken 178948 times.
✓ Branch 3 taken 269002203 times.
269002203 if(layer < 0 || layer > 6) return true;
3898
2/2
✓ Branch 0 taken 259588626 times.
✓ Branch 1 taken 9413577 times.
269002203 if(get_qr(qr_OLD_LENS_LAYEREFFECT))
3899 {
3900
2/2
✓ Branch 0 taken 209710465 times.
✓ Branch 1 taken 49878161 times.
259588626 if(!layer) return true;
3901
8/8
✓ Branch 0 taken 34922371 times.
✓ Branch 1 taken 174788094 times.
✓ Branch 2 taken 258970 times.
✓ Branch 3 taken 34663401 times.
✓ Branch 4 taken 143758 times.
✓ Branch 5 taken 163336 times.
✓ Branch 6 taken 326536 times.
✓ Branch 7 taken 34480623 times.
209710465 if((layer==(int32_t)(scr->lens_layer&7)+1) && ((scr->lens_layer&llLENSSHOWS && !lensclk) || (scr->lens_layer&llLENSHIDES && lensclk)))
3902 489872 return false;
3903 209268717 }
3904 else
3905 {
3906
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9413577 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9413577 times.
9413577 if((lensclk ? scr->lens_hide : scr->lens_show) & (1<<layer))
3907 return false;
3908 }
3909 218682294 return true;
3910 268823255 }
3911
3912 156158207 void do_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3913 {
3914 156158207 bool showlayer = true;
3915 156158207 mapscr* base_scr = screen_handle.base_scr;
3916 156158207 int layer = screen_handle.layer;
3917
2/2
✓ Branch 0 taken 42084449 times.
✓ Branch 1 taken 114073758 times.
156158207 int target = type ? type : layer;
3918
3/4
✓ Branch 0 taken 114073758 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20230988 times.
✓ Branch 3 taken 21853461 times.
156158207 switch(target)
3919 {
3920 case -2:
3921
1/2
✓ Branch 0 taken 20230988 times.
✗ Branch 1 not taken.
20230988 if(!show_layer_push)
3922 showlayer = false;
3923 20230988 break;
3924
3925 case -1:
3926
1/2
✓ Branch 0 taken 21853461 times.
✗ Branch 1 not taken.
21853461 if(!show_layer_over)
3927 showlayer = false;
3928 21853461 break;
3929
3930 case 1: case 2: case 3:
3931 case 4: case 5: case 6:
3932 114073758 showlayer = show_layers[target];
3933 114073758 break;
3934 }
3935
3936
2/2
✓ Branch 0 taken 42084449 times.
✓ Branch 1 taken 114073758 times.
156158207 if(!type)
3937 {
3938
2/2
✓ Branch 0 taken 113937560 times.
✓ Branch 1 taken 136198 times.
114073758 if(!lenscheck(base_scr,layer))
3939 136198 showlayer = false;
3940 114073758 }
3941
3942
2/2
✓ Branch 0 taken 136198 times.
✓ Branch 1 taken 156022009 times.
156158207 if(showlayer)
3943 {
3944
6/6
✓ Branch 0 taken 61903620 times.
✓ Branch 1 taken 94118389 times.
✓ Branch 2 taken 21286883 times.
✓ Branch 3 taken 40616737 times.
✓ Branch 4 taken 56123 times.
✓ Branch 5 taken 21230760 times.
156022009 if (screen_handle.scr && (type || !(base_scr->hidelayers & (1 << (layer)))))
3945 {
3946 61847497 do_scrolling_layer(bmp, type, screen_handle, x, y);
3947
4/4
✓ Branch 0 taken 21230760 times.
✓ Branch 1 taken 40616737 times.
✓ Branch 2 taken 19233930 times.
✓ Branch 3 taken 1996830 times.
61847497 if(!type && !get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
3948
2/2
✓ Branch 0 taken 1996254 times.
✓ Branch 1 taken 576 times.
1997406 if(mblock2.draw(bmp,layer))
3949 576 do_primitives(bmp, SPLAYER_MOVINGBLOCK);
3950 61847497 }
3951 156022009 }
3952 156158207 }
3953
3954 103025421 void do_layer_primitives(BITMAP *bmp, int32_t layer)
3955 {
3956 103025421 bool showlayer = true;
3957
3958
2/4
✓ Branch 0 taken 103025421 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 103025421 times.
103025421 if(layer >= 0 && layer <= 6)
3959 {
3960 103025421 showlayer = show_layers[layer];
3961
3962
2/2
✓ Branch 0 taken 102898819 times.
✓ Branch 1 taken 126602 times.
103025421 if(!lenscheck(origin_scr,layer))
3963 126602 showlayer = false;
3964 103025421 }
3965
3966
2/2
✓ Branch 0 taken 126602 times.
✓ Branch 1 taken 102898819 times.
103025421 if (showlayer)
3967 102898819 do_primitives(bmp, layer);
3968 103025421 }
3969
3970 // Called by do_walkflags
3971 void put_walkflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
3972 {
3973 newcombo const &c = combobuf[cmbdat];
3974
3975 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
3976
3977 int32_t xx = x-xofs;
3978 int32_t yy = y+playing_field_offset-yofs;
3979
3980 int32_t bridgedetected = 0;
3981
3982 for(int32_t i=0; i<4; i++)
3983 {
3984 int32_t tx=((i&2)<<2)+xx - viewport.x;
3985 int32_t ty=((i&1)<<3)+yy - viewport.y;
3986 int32_t tx2=((i&2)<<2)+x - viewport.x;
3987 int32_t ty2=((i&1)<<3)+y - viewport.y;
3988 for (int32_t j = lyr-1; j <= 1; j++)
3989 {
3990 if (get_qr(qr_OLD_BRIDGE_COMBOS))
3991 {
3992 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && !_walkflag_layer(tx2,ty2,j))
3993 {
3994 bridgedetected |= (1<<i);
3995 }
3996 }
3997 else
3998 {
3999 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && _effectflag_layer(tx2,ty2,j))
4000 {
4001 bridgedetected |= (1<<i);
4002 }
4003 }
4004 }
4005 if ((bridgedetected & (1<<i)))
4006 {
4007 if (i >= 3) break;
4008 else continue;
4009 }
4010 bool doladdercheck = true;
4011
4012 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4013 {
4014 for(int32_t k=0; k<8; k+=2)
4015 for(int32_t j=0; j<8; j+=2)
4016 if(((k+j)/2)%2)
4017 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,makecol(85,85,255));
4018 }
4019 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4020 {
4021 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4022 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4023 rectfill(dest,tx,ty,tx+7,ty+7,makecol(85,85,255));
4024 else rectfill(dest,tx,ty,tx+7,ty+7,makecol(170,170,170));
4025 }
4026
4027 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4028 {
4029 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4030 {
4031 for(int32_t k=0; k<8; k+=2)
4032 for(int32_t j=0; j<8; j+=2)
4033 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,((k+j)/2)%2 ? makecol(165,105,8) : makecol(170,170,170));
4034 }
4035 else
4036 {
4037 int32_t color = makecol(178,36,36);
4038
4039 if(isstepable(cmbdat)&& (!doladdercheck))
4040 color=makecol(165,105,8);
4041 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4042 color=makecol(170,170,170);
4043
4044 rectfill(dest,tx,ty,tx+7,ty+7,color);
4045 }
4046 }
4047 }
4048
4049 // Draw damage combos
4050 bool dmg = combo_class_buf[combobuf[MAPCOMBO2(-1,xx,yy)].type].modify_hp_amount
4051 || combo_class_buf[combobuf[MAPCOMBO2(0,xx,yy)].type].modify_hp_amount
4052 || combo_class_buf[combobuf[MAPCOMBO2(1,xx,yy)].type].modify_hp_amount;
4053
4054 if(dmg)
4055 {
4056 int32_t color = makecol(255,255,0);
4057 if (bridgedetected <= 0)
4058 {
4059 for(int32_t k=0; k<16; k+=2)
4060 for(int32_t j=0; j<16; j+=2)
4061 if(((k+j)/2)%2)
4062 {
4063 int32_t x0 = x - viewport.x;
4064 int32_t y0 = y - viewport.y;
4065 rectfill(dest,x0+k,y0+j,x0+k+1,y0+j+1,color);
4066 }
4067 }
4068 else
4069 {
4070 for(int32_t i=0; i<4; i++)
4071 {
4072 if (!(bridgedetected & (1<<i)))
4073 {
4074 int32_t tx=((i&2)<<2)+x - viewport.x;
4075 int32_t ty=((i&1)<<3)+y - viewport.y;
4076 for(int32_t k=0; k<8; k+=2)
4077 for(int32_t j=0; j<8; j+=2)
4078 if((k+j)%4 < 2) rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,color);
4079 }
4080 }
4081 }
4082 }
4083 }
4084 static void put_walkflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4085 {
4086 ALLEGRO_COLOR col_solid = al_map_rgba(178,36,36,info_opacity);
4087 ALLEGRO_COLOR col_water1 = al_map_rgba(85,85,255,info_opacity);
4088 ALLEGRO_COLOR col_lhook = al_map_rgba(170,170,170,info_opacity);
4089 ALLEGRO_COLOR col_stepable = al_map_rgba(165,105,8,info_opacity);
4090 ALLEGRO_COLOR col_dmg = al_map_rgba(255,255,0,info_opacity);
4091 newcombo const &c = combobuf[cmbdat];
4092
4093 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
4094
4095 int32_t xx = x-viewport.x;
4096 int32_t yy = y+playing_field_offset-viewport.y;
4097
4098 int32_t bridgedetected = 0;
4099
4100 // Draw damage combos
4101 bool dmg = combo_class_buf[c.type].modify_hp_amount;
4102
4103 for(int32_t i=0; i<4; i++)
4104 {
4105 int32_t tx=((i&2)<<2)+xx;
4106 int32_t ty=((i&1)<<3)+yy;
4107 int32_t tx2=((i&2)<<2)+x;
4108 int32_t ty2=((i&1)<<3)+y;
4109 for (int32_t m = lyr-1; m <= 1; m++)
4110 {
4111 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4112 {
4113 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && !_walkflag_layer(tx2, ty2, m))
4114 {
4115 bridgedetected |= (1<<i);
4116 }
4117 }
4118 else
4119 {
4120 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && _effectflag_layer(tx2, ty2, m))
4121 {
4122 bridgedetected |= (1<<i);
4123 }
4124 }
4125 }
4126 if ((bridgedetected & (1<<i)))
4127 continue;
4128 bool doladdercheck = true;
4129
4130 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4131 {
4132 for(int32_t k=0; k<8; k+=2)
4133 for(int32_t j=0; j<8; j+=2)
4134 if(((k+j)/2)%2)
4135 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_water1);
4136 }
4137 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4138 {
4139 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4140 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4141 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_water1);
4142 else al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_lhook);
4143 }
4144
4145 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4146 {
4147 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4148 {
4149 for(int32_t k=0; k<8; k+=2)
4150 for(int32_t j=0; j<8; j+=2)
4151 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,((k+j)/2)%2 ? col_stepable : col_lhook);
4152 }
4153 else
4154 {
4155 ALLEGRO_COLOR* color = &col_solid;
4156
4157 if(isstepable(cmbdat)&& (!doladdercheck))
4158 color=&col_stepable;
4159 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4160 color=&col_lhook;
4161
4162 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,*color);
4163 }
4164 }
4165
4166 if(dmg)
4167 {
4168 for(int32_t k=0; k<8; k+=2)
4169 for(int32_t j=0; j<8; j+=2)
4170 if((k+j)%4 < 2) al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_dmg);
4171 }
4172 }
4173 }
4174
4175 void put_effectflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
4176 {
4177 newcombo const &c = combobuf[cmbdat];
4178
4179 int32_t xx = x-xofs-viewport.x;
4180 int32_t yy = y+playing_field_offset-yofs-viewport.y;
4181
4182 for(int32_t i=0; i<4; i++)
4183 {
4184 int32_t tx=((i&2)<<2)+xx;
4185 int32_t ty=((i&1)<<3)+yy;
4186
4187 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4188 {
4189 int32_t color = vc(10);
4190
4191 rectfill(dest,tx,ty,tx+7,ty+7,color);
4192 }
4193 }
4194 }
4195 static void put_effectflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4196 {
4197 ALLEGRO_COLOR col_eff = al_map_rgba(85,255,85,info_opacity);
4198 newcombo const &c = combobuf[cmbdat];
4199
4200 int32_t xx = x-viewport.x;
4201 int32_t yy = y+playing_field_offset-viewport.y;
4202
4203 for(int32_t i=0; i<4; i++)
4204 {
4205 int32_t tx=((i&2)<<2)+xx;
4206 int32_t ty=((i&1)<<3)+yy;
4207
4208 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4209 {
4210 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_eff);
4211 }
4212 }
4213 }
4214
4215 void draw_ladder_platform(BITMAP* dest, int32_t x, int32_t y, int32_t c)
4216 {
4217 for(auto cx = 0; cx < 256; cx += 16)
4218 {
4219 for(auto cy = 0; cy < 176; cy += 16)
4220 {
4221 if(isSVLadder(cx,cy))
4222 {
4223 auto nx = cx+x, ny = cy+y;
4224 if(cy && !isSVLadder(cx,cy-16))
4225 line(dest,nx,ny,nx+15,ny,c);
4226 rectfill(dest,nx,ny,nx+3,ny+15,c);
4227 rectfill(dest,nx+12,ny,nx+15,ny+15,c);
4228 rectfill(dest,nx+4,ny+2,nx+11,ny+5,c);
4229 rectfill(dest,nx+4,ny+10,nx+11,ny+13,c);
4230 }
4231 else if(isSVPlatform(cx,cy))
4232 {
4233 line(dest,cx+x,cy+y,cx+x+15,cy+y,c);
4234 }
4235 }
4236 }
4237 }
4238 void draw_ladder_platform_a5(int32_t x, int32_t y, ALLEGRO_COLOR c)
4239 {
4240 for(auto cx = 0; cx < 256; cx += 16)
4241 {
4242 for(auto cy = 0; cy < 176; cy += 16)
4243 {
4244 if(isSVLadder(cx,cy))
4245 {
4246 auto nx = cx+x, ny = cy+y;
4247 if(cy && !isSVLadder(cx,cy-16))
4248 al_draw_line(nx,ny,nx+15,ny,c,1);
4249 al_draw_filled_rectangle(nx,ny,nx+4,ny+16,c);
4250 al_draw_filled_rectangle(nx+12,ny,nx+16,ny+16,c);
4251 al_draw_filled_rectangle(nx+4,ny+2,nx+12,ny+6,c);
4252 al_draw_filled_rectangle(nx+4,ny+10,nx+12,ny+14,c);
4253 }
4254 else if(isSVPlatform(cx,cy))
4255 {
4256 al_draw_line(cx+x,cy+y,cx+x+15,cy+y,c,1);
4257 }
4258 }
4259 }
4260 }
4261
4262 // Walkflags L4 cheat
4263 void do_walkflags(const screen_handles_t& screen_handles, int32_t x, int32_t y)
4264 {
4265 if (!show_walkflags)
4266 return;
4267
4268 start_info_bmp();
4269
4270 mapscr* scr = screen_handles[0].scr;
4271 for(int32_t i=0; i<176; i++)
4272 {
4273 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4274 }
4275
4276 for(int32_t k=0; k<2; k++)
4277 {
4278 scr = screen_handles[k + 1].scr;
4279
4280 if (scr)
4281 {
4282 for(int32_t i=0; i<176; i++)
4283 {
4284 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], k%2+1);
4285 }
4286 }
4287 }
4288
4289 end_info_bmp();
4290 }
4291
4292 void do_walkflags(int32_t x, int32_t y)
4293 {
4294 if (!show_walkflags)
4295 return;
4296
4297 x += -viewport.x;
4298 y += playing_field_offset - viewport.y;
4299
4300 start_info_bmp();
4301
4302 draw_ladder_platform_a5(x,y,al_map_rgba(165,105,8,info_opacity));
4303 draw_solid_objects_a5(x,y,al_map_rgba(178,36,36,info_opacity));
4304 draw_slopes_a5(x,y,al_map_rgba(255,85,255,info_opacity));
4305
4306 end_info_bmp();
4307 }
4308
4309 // Effectflags L4 cheat
4310 void do_effectflags(mapscr* scr, int32_t x, int32_t y)
4311 {
4312 if(show_effectflags)
4313 {
4314 start_info_bmp();
4315
4316 for(int32_t i=0; i<176; i++)
4317 {
4318 put_effectflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4319 }
4320
4321 end_info_bmp();
4322 }
4323 }
4324
4325 272141 void calc_darkroom_combos(mapscr* scr, int offx, int offy)
4326 {
4327 272141 int map = scr->map;
4328 272141 int screen = scr->screen;
4329
4330
2/2
✓ Branch 0 taken 1904987 times.
✓ Branch 1 taken 272141 times.
2177128 for(int32_t lyr = 0; lyr < 7; ++lyr)
4331 {
4332 1904987 mapscr* scr = get_scr_layer(map, screen, lyr);
4333
2/2
✓ Branch 0 taken 1279588 times.
✓ Branch 1 taken 625399 times.
1904987 if (!scr->is_valid()) continue;
4334
4335
2/2
✓ Branch 0 taken 225207488 times.
✓ Branch 1 taken 1279588 times.
226487076 for(int32_t q = 0; q < 176; ++q)
4336 {
4337 225207488 newcombo const& cmb = combobuf[scr->data[q]];
4338
2/2
✓ Branch 0 taken 224602869 times.
✓ Branch 1 taken 604619 times.
225207488 if(cmb.type == cTORCH)
4339 {
4340 604619 do_torch_combo(cmb, COMBOX(q)+8+offx, COMBOY(q)+8+offy, darkscr_bmp);
4341 604619 }
4342 225207488 }
4343 1279588 }
4344 272141 }
4345
4346 272141 void calc_darkroom_ffcs(mapscr* scr, int offx, int offy)
4347 {
4348 272141 word c = scr->numFFC();
4349
2/2
✓ Branch 0 taken 537406 times.
✓ Branch 1 taken 272141 times.
809547 for(int q = 0; q < c; ++q)
4350 {
4351 537406 newcombo const& cmb = combobuf[scr->ffcs[q].data];
4352
2/2
✓ Branch 0 taken 522598 times.
✓ Branch 1 taken 14808 times.
537406 if(cmb.type == cTORCH)
4353 {
4354 14808 int cx = scr->ffcs[q].x.getInt()+(scr->ffEffectWidth(q)/2)+offx;
4355 14808 int cy = (scr->ffcs[q].y.getInt())+(scr->ffEffectHeight(q)/2)+offy;
4356 14808 do_torch_combo(cmb, cx, cy, darkscr_bmp);
4357 14808 }
4358 537406 }
4359 272141 }
4360
4361 struct nearby_screen_t
4362 {
4363 int screen;
4364 int offx;
4365 int offy;
4366 screen_handles_t screen_handles;
4367 };
4368 typedef std::vector<nearby_screen_t> nearby_screens_t;
4369
4370 15487811 static nearby_screens_t get_nearby_screens_non_scrolling_region()
4371 {
4372 15487811 nearby_screens_t nearby_screens;
4373
4374 15487811 mapscr* base_scr = origin_scr;
4375
1/2
✓ Branch 0 taken 15487811 times.
✗ Branch 1 not taken.
15487811 auto& nearby_screen = nearby_screens.emplace_back();
4376 15487811 nearby_screen.screen = cur_screen;
4377
1/2
✓ Branch 0 taken 15487811 times.
✗ Branch 1 not taken.
15487811 nearby_screen.screen_handles = create_screen_handles(base_scr);
4378
4379 15487811 return nearby_screens;
4380
1/2
✓ Branch 0 taken 15487811 times.
✗ Branch 1 not taken.
15487811 }
4381
4382 48296 static nearby_screens_t get_nearby_screens_scrolling_region()
4383 {
4384 48296 nearby_screens_t nearby_screens;
4385
4386
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x0 = viewport.left() / 256;
4387
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x1 = (viewport.right() - 1) / 256;
4388
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y0 = viewport.top() / 176;
4389
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y1 = (viewport.bottom() - 1) / 176;
4390
4391
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x0 = std::clamp(screens_x0, 0, 15);
4392
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x1 = std::clamp(screens_x1, 0, 15);
4393
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y0 = std::clamp(screens_y0, 0, 8);
4394
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y1 = std::clamp(screens_y1, 0, 8);
4395
4396
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 79928 times.
128224 for (int x = screens_x0; x <= screens_x1; x++)
4397 {
4398
2/2
✓ Branch 0 taken 169672 times.
✓ Branch 1 taken 79928 times.
249600 for (int y = screens_y0; y <= screens_y1; y++)
4399 {
4400 169672 int screen = cur_screen + x + y*16;
4401
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!is_in_current_region(screen)) continue;
4402
4403
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 mapscr* base_scr = get_scr(screen);
4404
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!base_scr->is_valid()) continue;
4405
4406
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
4407
4408
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto& nearby_screen = nearby_screens.emplace_back();
4409 169672 nearby_screen.screen = screen;
4410 169672 nearby_screen.offx = offx;
4411 169672 nearby_screen.offy = offy;
4412
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 nearby_screen.screen_handles = create_screen_handles(base_scr);
4413 169672 }
4414 79928 }
4415
4416 48296 return nearby_screens;
4417
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 }
4418
4419 3658 static nearby_screens_t get_nearby_screens_smooth_maze()
4420 {
4421 3658 nearby_screens_t nearby_screens;
4422
4423
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x0 = viewport.left() / 256;
4424
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x1 = (viewport.right() - 1) / 256;
4425
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y0 = viewport.top() / 176;
4426
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y1 = (viewport.bottom() - 1) / 176;
4427
4428
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.left() < 0) screens_x0--;
4429
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.top() < 0) screens_y0--;
4430
4431
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 7308 times.
10966 for (int x = screens_x0; x <= screens_x1; x++)
4432 {
4433
2/2
✓ Branch 0 taken 18600 times.
✓ Branch 1 taken 7308 times.
25908 for (int y = screens_y0; y <= screens_y1; y++)
4434 {
4435 18600 int screen = -1;
4436 mapscr* base_scr;
4437 int offx, offy;
4438
4439 18600 mapscr* maze_scr = maze_state.scr;
4440 18600 int maze_screen = maze_scr->screen;
4441
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_x = get_region_relative_dx(maze_screen);
4442
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_y = get_region_relative_dy(maze_screen);
4443 18600 int maze_screen_dx = x - maze_screen_x;
4444 18600 int maze_screen_dy = y - maze_screen_y;
4445 18600 int exitdir = maze_scr->exitdir;
4446
4447 bool should_draw_maze_screen;
4448
2/2
✓ Branch 0 taken 9052 times.
✓ Branch 1 taken 9548 times.
18600 if (maze_state.lost)
4449 {
4450 9548 should_draw_maze_screen = true;
4451 9548 }
4452 else
4453 {
4454 9052 should_draw_maze_screen = true;
4455
4/6
✓ Branch 0 taken 9052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6844 times.
✓ Branch 3 taken 2208 times.
✓ Branch 4 taken 6844 times.
✗ Branch 5 not taken.
9052 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != exitdir && XY_DELTA_TO_DIR(0, maze_screen_dy) != exitdir;
4456
2/2
✓ Branch 0 taken 3850 times.
✓ Branch 1 taken 5202 times.
9052 if (maze_state.enter_dir != dir_invalid)
4457
4/6
✓ Branch 0 taken 3850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3304 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 3304 times.
✗ Branch 5 not taken.
3850 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != maze_state.enter_dir && XY_DELTA_TO_DIR(0, maze_screen_dy) != maze_state.enter_dir;
4458 }
4459
4460
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (should_draw_maze_screen)
4461 {
4462 16048 screen = maze_state.scr->screen;
4463 16048 base_scr = maze_state.scr;
4464
1/2
✓ Branch 0 taken 16048 times.
✗ Branch 1 not taken.
16048 std::tie(offx, offy) = translate_screen_coordinates_to_world(cur_screen + x + y*16);
4465 16048 }
4466
4467
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (screen == -1)
4468 {
4469 2552 screen = cur_screen + x + y*16;
4470
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!is_in_current_region(screen)) continue;
4471
4472
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 base_scr = get_scr(screen);
4473
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!base_scr->is_valid()) continue;
4474
4475
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 std::tie(offx, offy) = translate_screen_coordinates_to_world(screen);
4476 2552 }
4477
4478
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 auto& nearby_screen = nearby_screens.emplace_back();
4479 18600 nearby_screen.screen = screen;
4480 18600 nearby_screen.offx = offx;
4481 18600 nearby_screen.offy = offy;
4482
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 nearby_screen.screen_handles = create_screen_handles(base_scr);
4483 18600 }
4484 7308 }
4485
4486 3658 return nearby_screens;
4487
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 }
4488
4489 15539765 static nearby_screens_t get_nearby_screens()
4490 {
4491
4/4
✓ Branch 0 taken 9214 times.
✓ Branch 1 taken 15530551 times.
✓ Branch 2 taken 3658 times.
✓ Branch 3 taken 5556 times.
15539765 if (maze_state.active && maze_state.loopy)
4492 3658 return get_nearby_screens_smooth_maze();
4493
4494
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 15487811 times.
15536107 if (is_in_scrolling_region())
4495 48296 return get_nearby_screens_scrolling_region();
4496
4497 15487811 return get_nearby_screens_non_scrolling_region();
4498 15539765 }
4499
4500 202038438 static void for_every_nearby_screen(const nearby_screens_t& nearby_screens, const std::function <void (screen_handles_t, int, int, int)>& fn)
4501 {
4502
2/2
✓ Branch 0 taken 203823040 times.
✓ Branch 1 taken 202038438 times.
405861478 for (auto& nearby_screen : nearby_screens)
4503 203823040 fn(nearby_screen.screen_handles, nearby_screen.screen, nearby_screen.offx, nearby_screen.offy);
4504 202038438 }
4505
4506 124318120 static void draw_msgstr(byte layer, BITMAP* dest = nullptr)
4507 {
4508
2/2
✓ Branch 0 taken 15539765 times.
✓ Branch 1 taken 108778355 times.
124318120 if(layer != msgstr_layer) return;
4509
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 if(!dest) dest = framebuf;
4510
4511
2/2
✓ Branch 0 taken 679438 times.
✓ Branch 1 taken 14860327 times.
15539765 if(!(msg_bg_display_buf->clip))
4512 {
4513 679438 blit_msgstr_bg(dest,0,0,0,playing_field_offset,256,176);
4514 679438 }
4515
4516
2/2
✓ Branch 0 taken 679438 times.
✓ Branch 1 taken 14860327 times.
15539765 if(!(msg_portrait_display_buf->clip))
4517 {
4518 679438 blit_msgstr_prt(dest,0,0,0,playing_field_offset,256,176);
4519 679438 }
4520
4521
2/2
✓ Branch 0 taken 692845 times.
✓ Branch 1 taken 14846920 times.
15539765 if(!(msg_txt_display_buf->clip))
4522 {
4523 692845 blit_msgstr_fg(dest,0,0,0,playing_field_offset,256,176);
4524 692845 }
4525 124318120 }
4526
4527 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y);
4528
4529 62159060 static void set_draw_screen_clip(BITMAP* bmp)
4530 {
4531 62159060 set_clip_rect(bmp, draw_screen_clip_rect_x1, draw_screen_clip_rect_y1, draw_screen_clip_rect_x2, draw_screen_clip_rect_y2);
4532 62159060 }
4533
4534 46119039 void draw_screen(bool showhero, bool runGeneric)
4535 {
4536 46119039 clear_info_bmp();
4537
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46119039 times.
46119039 if((GameFlags & (GAMEFLAG_SCRIPTMENU_ACTIVE|GAMEFLAG_F6SCRIPT_ACTIVE))!=0)
4538 {
4539 FFCore.doScriptMenuDraws();
4540 return;
4541 }
4542
4543
2/2
✓ Branch 0 taken 31180939 times.
✓ Branch 1 taken 14938100 times.
46119039 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_PRE_DRAW);
4544
4545 46119039 clear_bitmap(framebuf);
4546 46119039 clear_clip_rect(framebuf);
4547
4548 46119039 int32_t cmby2=0;
4549
4550 // Draw some background layers
4551 46119039 clear_bitmap(scrollbuf);
4552
4553 46119039 auto nearby_screens = get_nearby_screens();
4554
4555 // Handle layer 2/3 possibly being background layers.
4556
1/2
✓ Branch 0 taken 46119039 times.
✗ Branch 1 not taken.
61795122 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4557 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4558
2/2
✓ Branch 0 taken 15548802 times.
✓ Branch 1 taken 127281 times.
15676083 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4559 127281 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4560 15676083 });
4561
4562
2/2
✓ Branch 0 taken 127281 times.
✓ Branch 1 taken 45991758 times.
46119039 if (XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4563 {
4564
1/2
✓ Branch 0 taken 127281 times.
✗ Branch 1 not taken.
127281 do_layer_primitives(scrollbuf, 2);
4565
1/2
✓ Branch 0 taken 127281 times.
✗ Branch 1 not taken.
127281 particles.draw(scrollbuf, true, 2);
4566 127281 }
4567
2/2
✓ Branch 0 taken 15539765 times.
✓ Branch 1 taken 30579274 times.
46119039 _do_current_ffc_layer(scrollbuf, -2);
4568
2/2
✓ Branch 0 taken 127281 times.
✓ Branch 1 taken 15412484 times.
15539765 if (XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4569
1/2
✓ Branch 0 taken 127281 times.
✗ Branch 1 not taken.
127281 draw_msgstr(2, scrollbuf);
4570
4571
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4572 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4573
2/2
✓ Branch 0 taken 15583424 times.
✓ Branch 1 taken 92659 times.
15676083 if (XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4574 92659 do_layer(scrollbuf, 0, screen_handles[3], offx, offy);
4575 15676083 });
4576
4577
2/2
✓ Branch 0 taken 92659 times.
✓ Branch 1 taken 15447106 times.
15539765 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4578 {
4579
1/2
✓ Branch 0 taken 92659 times.
✗ Branch 1 not taken.
92659 do_layer_primitives(scrollbuf, 3);
4580
1/2
✓ Branch 0 taken 92659 times.
✗ Branch 1 not taken.
92659 particles.draw(scrollbuf, true, 3);
4581 92659 }
4582
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(scrollbuf, -3);
4583
2/2
✓ Branch 0 taken 92659 times.
✓ Branch 1 taken 15447106 times.
15539765 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4584
1/2
✓ Branch 0 taken 92659 times.
✗ Branch 1 not taken.
92659 draw_msgstr(3, scrollbuf);
4585
4586 // Draw the main combo screens ("layer 0").
4587
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4588 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4589
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15676083 times.
15676083 if (lenscheck(base_scr, 0))
4590 {
4591 15676083 putscr(base_scr, scrollbuf, offx, offy + playing_field_offset);
4592 15676083 }
4593 15676083 });
4594
4595
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
15539765 if (lenscheck(hero_scr, 0))
4596 {
4597
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15073716 times.
15539765 if(!get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4598
3/4
✓ Branch 0 taken 466049 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4136 times.
✓ Branch 3 taken 461913 times.
470185 if(mblock2.draw(scrollbuf,0))
4599
1/2
✓ Branch 0 taken 4136 times.
✗ Branch 1 not taken.
4136 do_primitives(scrollbuf, SPLAYER_MOVINGBLOCK);
4600 15539765 }
4601
4602 // Lens hints, then primitives, then particles.
4603
6/10
✓ Branch 0 taken 15529736 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15529736 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15529736 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5876 times.
✓ Branch 9 taken 4153 times.
15539765 if((lensclk || (get_debug() && zc_getkey(KEY_L))) && !get_qr(qr_OLDLENSORDER))
4604 {
4605
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 draw_lens_under(scrollbuf, false);
4606
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4607 5876 }
4608
4609
2/4
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15539765 times.
✗ Branch 3 not taken.
15539765 if(show_layers[0] && lenscheck(hero_scr,0))
4610
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(scrollbuf, 0);
4611
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(scrollbuf, true, 0);
4612
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(scrollbuf, 0);
4613
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(0, scrollbuf);
4614
4615
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_draw_screen_clip(scrollbuf);
4616
4617
2/2
✓ Branch 0 taken 15196506 times.
✓ Branch 1 taken 343259 times.
15539765 if(!(get_qr(qr_LAYER12UNDERCAVE)))
4618 {
4619
4/4
✓ Branch 0 taken 15194632 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 15106248 times.
30356386 if(showhero &&
4620
4/6
✓ Branch 0 taken 15194632 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15159880 times.
✓ Branch 3 taken 34752 times.
✓ Branch 4 taken 15159880 times.
✗ Branch 5 not taken.
15194632 ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom)))
4621 {
4622
3/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 34752 times.
88384 if(Hero.getAction()==climbcovertop)
4623 {
4624 34752 cmby2=16;
4625 34752 }
4626
2/4
✓ Branch 0 taken 53632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53632 times.
53632 else if(Hero.getAction()==climbcoverbottom)
4627 {
4628 53632 cmby2=-16;
4629 53632 }
4630
4631
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw2(scrollbuf,true);
4632
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 Hero.draw(scrollbuf);
4633
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw(scrollbuf,true);
4634
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccx = (int32_t)Hero.getClimbCoverX();
4635
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccy = (int32_t)Hero.getClimbCoverY();
4636
4637
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4638
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4639
4640
4/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✓ Branch 5 taken 73152 times.
88384 if(int32_t(Hero.getX())&15)
4641 {
4642
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4643
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4644 15232 }
4645 88384 }
4646 15196506 }
4647
4648
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4649 15676083 do_layer(scrollbuf, 0, screen_handles[1], offx, offy); // LAYER 1
4650 15676083 });
4651
4652
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_layer_primitives(scrollbuf, 1);
4653
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(scrollbuf, true, 1);
4654
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(scrollbuf, 1);
4655
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(1, scrollbuf);
4656
4657 // Handle layer 2 NOT being used as background layers.
4658
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4659 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4660
2/2
✓ Branch 0 taken 127281 times.
✓ Branch 1 taken 15548802 times.
15676083 if (!XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4661 15548802 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4662 15676083 });
4663
4664
2/2
✓ Branch 0 taken 15412484 times.
✓ Branch 1 taken 127281 times.
15539765 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4665 {
4666
1/2
✓ Branch 0 taken 15412484 times.
✗ Branch 1 not taken.
15412484 do_layer_primitives(scrollbuf, 2);
4667
1/2
✓ Branch 0 taken 15412484 times.
✗ Branch 1 not taken.
15412484 particles.draw(scrollbuf, true, 2);
4668 15412484 }
4669
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(scrollbuf, 2);
4670
2/2
✓ Branch 0 taken 15412484 times.
✓ Branch 1 taken 127281 times.
15539765 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4671
1/2
✓ Branch 0 taken 15412484 times.
✗ Branch 1 not taken.
15412484 draw_msgstr(2, scrollbuf);
4672
4673
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(scrollbuf, SPLAYER_FFC_DRAW);
4674
4675
2/2
✓ Branch 0 taken 343259 times.
✓ Branch 1 taken 15196506 times.
15539765 if(get_qr(qr_LAYER12UNDERCAVE))
4676 {
4677
2/4
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 343259 times.
686518 if(showhero &&
4678
3/6
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 343259 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 343259 times.
✗ Branch 5 not taken.
343259 ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom)))
4679 {
4680 if(Hero.getAction()==climbcovertop)
4681 {
4682 cmby2=16;
4683 }
4684 else if(Hero.getAction()==climbcoverbottom)
4685 {
4686 cmby2=-16;
4687 }
4688
4689 decorations.draw2(scrollbuf,true);
4690 Hero.draw(scrollbuf);
4691 decorations.draw(scrollbuf,true);
4692 int32_t ccx = (int32_t)(Hero.getClimbCoverX());
4693 int32_t ccy = (int32_t)(Hero.getClimbCoverY());
4694
4695 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4696 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4697
4698 if(int32_t(Hero.getX())&15)
4699 {
4700 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4701 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4702 }
4703 }
4704 343259 }
4705
4706
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15073716 times.
15539765 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4707 {
4708
1/2
✓ Branch 0 taken 15073716 times.
✗ Branch 1 not taken.
30283750 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4709 15210034 do_layer(scrollbuf, -2, screen_handles[0], offx, offy); // push blocks!
4710
2/2
✓ Branch 0 taken 14478915 times.
✓ Branch 1 taken 731119 times.
15210034 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
4711 {
4712 731119 do_layer(scrollbuf, -2, screen_handles[1], offx, offy); // push blocks!
4713 731119 do_layer(scrollbuf, -2, screen_handles[2], offx, offy); // push blocks!
4714 731119 }
4715 15210034 });
4716
4717
1/2
✓ Branch 0 taken 15073716 times.
✗ Branch 1 not taken.
15073716 do_primitives(scrollbuf, SPLAYER_PUSHBLOCK);
4718 15073716 }
4719
4720 // Show walkflags cheat
4721
2/4
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15539765 times.
15539765 if (show_walkflags || show_effectflags)
4722 {
4723 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4724 do_walkflags(screen_handles, offx, offy);
4725 do_effectflags(screen_handles[0].base_scr, offx, offy);
4726 });
4727
4728 do_walkflags(0, 0);
4729 }
4730
4731
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 putscrdoors(nearby_screens, scrollbuf, 0, playing_field_offset);
4732
4733 // Lens hints, doors etc.
4734
4/8
✓ Branch 0 taken 15529736 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15529736 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15529736 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
15539765 if(lensclk || (get_debug() && zc_getkey(KEY_L)))
4735 {
4736
2/2
✓ Branch 0 taken 4153 times.
✓ Branch 1 taken 5876 times.
10029 if(get_qr(qr_OLDLENSORDER))
4737 {
4738
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 draw_lens_under(scrollbuf, false);
4739
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4740 4153 }
4741
4742
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 draw_lens_under(scrollbuf, true);
4743
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_2);
4744 10029 }
4745
4746 // Blit those layers onto framebuf
4747
4748
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_draw_screen_clip(framebuf);
4749
4750
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 blit(scrollbuf, framebuf, 0, 0, 0, 0, 256, 232);
4751
4752 // After this point, scrollbuf is no longer drawn to - so things like dosubscr have access to a "partially rendered" frame.
4753 // I think only used for COOLSCROLL==0? Seems like a silly feature...
4754
4755 // Draw the subscreen, without clipping
4756
2/2
✓ Branch 0 taken 9251384 times.
✓ Branch 1 taken 6288381 times.
15539765 if(!get_qr(qr_SUBSCREENOVERSPRITES))
4757 {
4758 9251384 bool dotime = false;
4759
4/6
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3412853 times.
✓ Branch 3 taken 5838531 times.
✓ Branch 4 taken 3412853 times.
✗ Branch 5 not taken.
9251384 if (replay_version_check(22)) dotime = game->should_show_time();
4760
1/2
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
9251384 put_passive_subscr(framebuf, 0, 0, dotime, sspUP);
4761 9251384 }
4762
4763 // Draw some sprites onto framebuf
4764
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_clip_rect(framebuf,0,0,256,232);
4765
4766
2/2
✓ Branch 0 taken 99496 times.
✓ Branch 1 taken 15440269 times.
15539765 if(!(pricesdisplaybuf->clip))
4767 {
4768
1/2
✓ Branch 0 taken 99496 times.
✗ Branch 1 not taken.
99496 masked_blit(pricesdisplaybuf,framebuf,0,0,0,playing_field_offset,256,176);
4769 99496 }
4770
4771
5/6
✓ Branch 0 taken 15494139 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15487811 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15539765 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4772 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4773
4774
8/10
✓ Branch 0 taken 15537891 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 15537891 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15503139 times.
✓ Branch 5 taken 34752 times.
✓ Branch 6 taken 15503139 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15449507 times.
✓ Branch 9 taken 53632 times.
15539765 if(showhero && ((Hero.getAction()!=climbcovertop)&&(Hero.getAction()!=climbcoverbottom)))
4775 {
4776
1/2
✓ Branch 0 taken 15449507 times.
✗ Branch 1 not taken.
15449507 Hero.draw_under(framebuf);
4777
4778
3/4
✓ Branch 0 taken 15449507 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141385 times.
✓ Branch 3 taken 15308122 times.
15449507 if(Hero.isSwimming())
4779 {
4780
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw2(framebuf,true);
4781
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 Hero.draw(framebuf);
4782
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw(framebuf,true);
4783 141385 }
4784 15449507 }
4785
4786
2/2
✓ Branch 0 taken 26095 times.
✓ Branch 1 taken 15513670 times.
15539765 if(drawguys)
4787 {
4788
4/4
✓ Branch 0 taken 1982674 times.
✓ Branch 1 taken 13530996 times.
✓ Branch 2 taken 991089 times.
✓ Branch 3 taken 991585 times.
15513670 if(get_qr(qr_NOFLICKER) || (frame&1))
4789 {
4790 // Just clips sprites if in a repeating, smooth maze.
4791
2/2
✓ Branch 0 taken 14512871 times.
✓ Branch 1 taken 9214 times.
14522085 bool do_clip = maze_state.active && maze_state.loopy;
4792
4793
3/4
✓ Branch 0 taken 23627227 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9105142 times.
✓ Branch 3 taken 14522085 times.
23627227 for(int32_t i=0; i<Ewpns.Count(); i++)
4794 {
4795
3/4
✓ Branch 0 taken 9105142 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✓ Branch 3 taken 8907199 times.
9105142 if(((weapon *)Ewpns.spr(i))->behind)
4796
2/4
✓ Branch 0 taken 197943 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✗ Branch 3 not taken.
197943 Ewpns.spr(i)->draw(framebuf);
4797 9105142 }
4798
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4799
4800
3/4
✓ Branch 0 taken 19197181 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4675096 times.
✓ Branch 3 taken 14522085 times.
19197181 for(int32_t i=0; i<Lwpns.Count(); i++)
4801 {
4802
3/4
✓ Branch 0 taken 4675096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✓ Branch 3 taken 4671891 times.
4675096 if(((weapon *)Lwpns.spr(i))->behind)
4803
2/4
✓ Branch 0 taken 3205 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✗ Branch 3 not taken.
3205 Lwpns.spr(i)->draw(framebuf);
4804 4675096 }
4805
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4806
4807
6/6
✓ Branch 0 taken 9785221 times.
✓ Branch 1 taken 4736864 times.
✓ Branch 2 taken 1348300 times.
✓ Branch 3 taken 8436921 times.
✓ Branch 4 taken 674011 times.
✓ Branch 5 taken 674289 times.
14522085 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4808 {
4809
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 9107274 times.
9110932 if (do_clip)
4810
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.drawshadow_smooth_maze(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4811 else
4812
1/2
✓ Branch 0 taken 9107274 times.
✗ Branch 1 not taken.
9107274 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4813 9110932 }
4814
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4815
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.draw_smooth_maze(framebuf);
4816 else
4817
1/2
✓ Branch 0 taken 14518427 times.
✗ Branch 1 not taken.
14518427 guys.draw(framebuf,true);
4818
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4819 {
4820 3658 int maze_screen = maze_state.scr->screen;
4821
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4822
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4823 3658 }
4824
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4825
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4826
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4827
4828
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 chainlinks.draw(framebuf,true);
4829
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4830 //Lwpns.draw(framebuf,true);
4831
4832
3/4
✓ Branch 0 taken 23627227 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9105142 times.
✓ Branch 3 taken 14522085 times.
23627227 for(int32_t i=0; i<Ewpns.Count(); i++)
4833 {
4834
3/4
✓ Branch 0 taken 9105142 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8907199 times.
✓ Branch 3 taken 197943 times.
9105142 if(!((weapon *)Ewpns.spr(i))->behind)
4835
2/4
✓ Branch 0 taken 8907199 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8907199 times.
✗ Branch 3 not taken.
8907199 Ewpns.spr(i)->draw(framebuf);
4836 9105142 }
4837
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4838
4839
3/4
✓ Branch 0 taken 19197181 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4675096 times.
✓ Branch 3 taken 14522085 times.
19197181 for(int32_t i=0; i<Lwpns.Count(); i++)
4840 {
4841
3/4
✓ Branch 0 taken 4675096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4671891 times.
✓ Branch 3 taken 3205 times.
4675096 if(!((weapon *)Lwpns.spr(i))->behind)
4842
2/4
✓ Branch 0 taken 4671891 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4671891 times.
✗ Branch 3 not taken.
4671891 Lwpns.spr(i)->draw(framebuf);
4843 4675096 }
4844
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4845
4846
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4847
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 items.draw_smooth_maze(framebuf);
4848 else
4849
1/2
✓ Branch 0 taken 14518427 times.
✗ Branch 1 not taken.
14518427 items.draw(framebuf,true);
4850
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4851 {
4852 3658 int maze_screen = maze_state.scr->screen;
4853
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4854
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4855 3658 }
4856
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4857
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4858
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4859 14522085 }
4860 else
4861 {
4862
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
4863 {
4864
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✓ Branch 3 taken 496727 times.
505372 if(((weapon *)Ewpns.spr(i))->behind)
4865
2/4
✓ Branch 0 taken 8645 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✗ Branch 3 not taken.
8645 Ewpns.spr(i)->draw(framebuf);
4866 505372 }
4867
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4868
4869
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
4870 {
4871
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 231146 times.
231146 if(((weapon *)Lwpns.spr(i))->behind)
4872 Lwpns.spr(i)->draw(framebuf);
4873 231146 }
4874
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4875
4876
3/4
✓ Branch 0 taken 228620 times.
✓ Branch 1 taken 762965 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228620 times.
991585 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4877 {
4878
1/2
✓ Branch 0 taken 228620 times.
✗ Branch 1 not taken.
228620 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4879 228620 }
4880
4881
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 items.draw(framebuf,false);
4882
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4883
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 chainlinks.draw(framebuf,false);
4884
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4885 //Lwpns.draw(framebuf,false);
4886
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 guys.draw(framebuf,false);
4887
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4888
4889
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
4890 {
4891
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✓ Branch 3 taken 8645 times.
505372 if(!((weapon *)Ewpns.spr(i))->behind)
4892 {
4893
2/4
✓ Branch 0 taken 496727 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✗ Branch 3 not taken.
496727 Ewpns.spr(i)->draw(framebuf);
4894 496727 }
4895 505372 }
4896
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4897
4898
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
4899 {
4900
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 if(!((weapon *)Lwpns.spr(i))->behind)
4901 {
4902
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 Lwpns.spr(i)->draw(framebuf);
4903 231146 }
4904 231146 }
4905
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4906 }
4907
4908
1/2
✓ Branch 0 taken 15513670 times.
✗ Branch 1 not taken.
15513670 guys.draw2(framebuf,true);
4909 15513670 }
4910
4911
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
15539765 if(mirror_portal.destdmap > -1)
4912 mirror_portal.draw(framebuf);
4913
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 portals.draw(framebuf,true);
4914
4915
8/10
✓ Branch 0 taken 15537891 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 15537891 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15503139 times.
✓ Branch 5 taken 34752 times.
✓ Branch 6 taken 15503139 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15449507 times.
✓ Branch 9 taken 53632 times.
15539765 if(showhero && ((Hero.getAction()!=climbcovertop)&& (Hero.getAction()!=climbcoverbottom)))
4916 {
4917
2/2
✓ Branch 0 taken 14989874 times.
✓ Branch 1 taken 459633 times.
15449507 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4918 {
4919
1/2
✓ Branch 0 taken 14989874 times.
✗ Branch 1 not taken.
14989874 mblock2.draw(framebuf,-1);
4920
1/2
✓ Branch 0 taken 14989874 times.
✗ Branch 1 not taken.
14989874 do_primitives(framebuf, SPLAYER_MOVINGBLOCK);
4921 14989874 }
4922
3/4
✓ Branch 0 taken 15449507 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15308122 times.
✓ Branch 3 taken 141385 times.
15449507 if(!Hero.isSwimming())
4923 {
4924
8/12
✓ Branch 0 taken 15308122 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15308122 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15288952 times.
✓ Branch 5 taken 19170 times.
✓ Branch 6 taken 15288952 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15288952 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1370 times.
✓ Branch 11 taken 15306752 times.
15308122 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4925 {
4926
2/2
✓ Branch 0 taken 18485 times.
✓ Branch 1 taken 15289637 times.
15308122 Hero.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4927 18485 }
4928
4929
6/8
✓ Branch 0 taken 15308122 times.
✓ Branch 1 taken 15289637 times.
✓ Branch 2 taken 15308122 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15308122 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15294058 times.
✓ Branch 7 taken 14064 times.
18485 if(Hero.getZ() <= (zfix)zinit.jump_hero_layer_threshold)
4930 {
4931
1/2
✓ Branch 0 taken 15294058 times.
✗ Branch 1 not taken.
15294058 decorations.draw2(framebuf,true);
4932
1/2
✓ Branch 0 taken 15294058 times.
✗ Branch 1 not taken.
15294058 Hero.draw(framebuf);
4933
1/2
✓ Branch 0 taken 15294058 times.
✗ Branch 1 not taken.
15294058 decorations.draw(framebuf,true);
4934 15294058 }
4935 15308122 }
4936 15449507 }
4937
4938
3/4
✓ Branch 0 taken 54880218 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39340453 times.
✓ Branch 3 taken 15539765 times.
54880218 for(int32_t i=0; i<guys.Count(); i++)
4939 {
4940
3/4
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15945464 times.
✓ Branch 3 taken 23394989 times.
39340453 if(((enemy*)guys.spr(i))->type == eeWALK)
4941 {
4942
3/4
✓ Branch 0 taken 15945464 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✓ Branch 3 taken 15938169 times.
15945464 if(((eStalfos*)guys.spr(i))->hashero)
4943 {
4944
2/4
✓ Branch 0 taken 7295 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✗ Branch 3 not taken.
7295 guys.spr(i)->draw(framebuf);
4945 7295 }
4946 15945464 }
4947
4948
3/4
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 507162 times.
✓ Branch 3 taken 38833291 times.
39340453 if(((enemy*)guys.spr(i))->type == eeWALLM)
4949 {
4950
3/4
✓ Branch 0 taken 507162 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✓ Branch 3 taken 505833 times.
507162 if(((eWallM*)guys.spr(i))->hashero)
4951 {
4952
2/4
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
1329 guys.spr(i)->draw(framebuf);
4953 1329 }
4954 507162 }
4955
4956
11/20
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39340453 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39340453 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 39340453 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 39340453 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 39340453 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 39340453 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 39340453 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 39340453 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1342694 times.
✓ Branch 19 taken 37997759 times.
39340453 if(guys.spr(i)->z+guys.spr(i)->fakez > Hero.getZ()+Hero.getFakeZ())
4957 {
4958 //Jumping enemies in front of Hero.
4959
2/4
✓ Branch 0 taken 1342694 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1342694 times.
✗ Branch 3 not taken.
1342694 guys.spr(i)->draw(framebuf);
4960 1342694 }
4961
1/2
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
39340453 do_primitives(framebuf, SPLAYER_NPC_ABOVEPLAYER_DRAW);
4962 39340453 }
4963
4964 // Draw some layers onto framebuf
4965
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_draw_screen_clip(framebuf);
4966
5/6
✓ Branch 0 taken 15494139 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15487811 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15539765 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4967 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4968
4969 // Handle layer 3 NOT being used as background layers.
4970
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4971 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4972
2/2
✓ Branch 0 taken 92659 times.
✓ Branch 1 taken 15583424 times.
15676083 if (!XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4973 15583424 do_layer(framebuf, 0, screen_handles[3], offx, offy);
4974 15676083 });
4975
4976
2/2
✓ Branch 0 taken 15447106 times.
✓ Branch 1 taken 92659 times.
15539765 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4977 {
4978
1/2
✓ Branch 0 taken 15447106 times.
✗ Branch 1 not taken.
15447106 do_layer_primitives(framebuf, 3);
4979
1/2
✓ Branch 0 taken 15447106 times.
✗ Branch 1 not taken.
15447106 particles.draw(framebuf, true, 3);
4980 15447106 }
4981
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 3);
4982
2/2
✓ Branch 0 taken 15447106 times.
✓ Branch 1 taken 92659 times.
15539765 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4983
1/2
✓ Branch 0 taken 15447106 times.
✗ Branch 1 not taken.
15447106 draw_msgstr(3);
4984
4985
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4986 15676083 do_layer(framebuf, 0, screen_handles[4], offx, offy);
4987 15676083 });
4988
4989
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_layer_primitives(framebuf, 4);
4990
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(framebuf, true, 4);
4991
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 4);
4992
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(4);
4993
4994
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4995 15676083 do_layer(framebuf, -1, screen_handles[0], offx, offy);
4996
2/2
✓ Branch 0 taken 14400195 times.
✓ Branch 1 taken 1275888 times.
15676083 if (get_qr(qr_OVERHEAD_COMBOS_L1_L2))
4997 {
4998 1275888 do_layer(framebuf, -1, screen_handles[1], offx, offy);
4999 1275888 do_layer(framebuf, -1, screen_handles[2], offx, offy);
5000 1275888 }
5001 15676083 });
5002
5003
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(framebuf, SPLAYER_OVERHEAD_CMB);
5004
5005 // Draw some flying sprites onto framebuf
5006
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 clear_clip_rect(framebuf);
5007
5/6
✓ Branch 0 taken 15494139 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15487811 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15539765 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5008 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5009
5010 //Jumping Hero and jumping enemies are drawn on this layer.
5011
5/8
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15539765 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15539765 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14064 times.
✓ Branch 7 taken 15525701 times.
15539765 if(Hero.getZ() > (zfix)zinit.jump_hero_layer_threshold)
5012 {
5013
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw2(framebuf,false);
5014
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 Hero.draw(framebuf);
5015
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 chainlinks.draw(framebuf,true);
5016
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
5017
5018
3/4
✓ Branch 0 taken 16806 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✓ Branch 3 taken 14064 times.
16806 for(int32_t i=0; i<Lwpns.Count(); i++)
5019 {
5020
9/16
✓ Branch 0 taken 2742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2742 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2742 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2742 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2742 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2742 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 239 times.
✓ Branch 15 taken 2503 times.
2742 if(Lwpns.spr(i)->z+Lwpns.spr(i)->fakez > (zfix)zinit.jump_hero_layer_threshold)
5021 {
5022
2/4
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
239 Lwpns.spr(i)->draw(framebuf);
5023 239 }
5024 2742 }
5025
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(framebuf, SPLAYER_LWEAP_ABOVE_DRAW);
5026
5027
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw(framebuf,false);
5028 14064 }
5029
5030
5/6
✓ Branch 0 taken 3288981 times.
✓ Branch 1 taken 12250784 times.
✓ Branch 2 taken 44334375 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32083591 times.
✓ Branch 5 taken 12250784 times.
47623356 if(!get_qr(qr_ENEMIESZAXIS)) for(int32_t i=0; i<guys.Count(); i++)
5031 {
5032
13/22
✓ Branch 0 taken 32083591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32083591 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27177493 times.
✓ Branch 5 taken 4906098 times.
✓ Branch 6 taken 27177493 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27177493 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27177493 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27177493 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 27177493 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 27177493 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27177493 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6568 times.
✓ Branch 21 taken 27170925 times.
32083591 if((isflier(guys.spr(i)->id)) || (guys.spr(i)->z+guys.spr(i)->fakez) > (zfix)zinit.jump_hero_layer_threshold)
5033 {
5034
2/4
✓ Branch 0 taken 4912666 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4912666 times.
✗ Branch 3 not taken.
4912666 guys.spr(i)->draw(framebuf);
5035 4912666 }
5036 44334375 }
5037 else
5038 {
5039
3/4
✓ Branch 0 taken 10545843 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✓ Branch 3 taken 3288981 times.
10545843 for(int32_t i=0; i<guys.Count(); i++)
5040 {
5041
13/22
✓ Branch 0 taken 7256862 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6081157 times.
✓ Branch 5 taken 1175705 times.
✓ Branch 6 taken 6081157 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6081157 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6081157 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 5594346 times.
✓ Branch 13 taken 486811 times.
✓ Branch 14 taken 5594346 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 5594346 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 5594346 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 5594346 times.
7256862 if((isflier(guys.spr(i)->id)) || guys.spr(i)->z > 0 || guys.spr(i)->fakez > 0)
5042 {
5043
2/4
✓ Branch 0 taken 1662516 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1662516 times.
✗ Branch 3 not taken.
1662516 guys.spr(i)->draw(framebuf);
5044 1662516 }
5045 7256862 }
5046 }
5047
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(framebuf, SPLAYER_NPC_AIRBORNE_DRAW);
5048
5049 // Draw the Moving Fairy above layer 3
5050
3/4
✓ Branch 0 taken 18684859 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3145094 times.
✓ Branch 3 taken 15539765 times.
18684859 for(int32_t i=0; i<items.Count(); i++)
5051
6/8
✓ Branch 0 taken 3145094 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69867 times.
✓ Branch 3 taken 3075227 times.
✓ Branch 4 taken 69867 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 60153 times.
✓ Branch 7 taken 9714 times.
3205247 if(itemsbuf[items.spr(i)->id].type == itype_fairy && itemsbuf[items.spr(i)->id].misc3)
5052
2/4
✓ Branch 0 taken 60153 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60153 times.
✗ Branch 3 not taken.
60153 items.spr(i)->draw(framebuf);
5053
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(framebuf, SPLAYER_FAIRYITEM_DRAW);
5054
5055 // Draw some layers onto framebuf
5056
5057
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_draw_screen_clip(framebuf);
5058
5059
2/2
✓ Branch 0 taken 15525413 times.
✓ Branch 1 taken 14352 times.
15539765 if (lightbeam_present)
5060 {
5061 14352 color_map = &trans_table2;
5062
2/2
✓ Branch 0 taken 13114 times.
✓ Branch 1 taken 1238 times.
14352 if(get_qr(qr_LIGHTBEAM_TRANSPARENT))
5063
1/2
✓ Branch 0 taken 13114 times.
✗ Branch 1 not taken.
13114 draw_trans_sprite(framebuf, lightbeam_bmp, 0, playing_field_offset);
5064 else
5065
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
1238 masked_blit(lightbeam_bmp, framebuf, 0, 0, 0, playing_field_offset, 256, 176);
5066 14352 color_map = &trans_table;
5067 14352 }
5068
5069
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5070 15676083 do_layer(framebuf, 0, screen_handles[5], offx, offy);
5071 15676083 });
5072
5073
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_layer_primitives(framebuf, 5);
5074
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(framebuf, true, 5);
5075
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 5);
5076
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(5);
5077
5078
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, -1); // 'overhead' freeform combos
5079
5080
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(framebuf, SPLAYER_OVERHEAD_FFC);
5081
5082
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5083 15676083 do_layer(framebuf, 0, screen_handles[6], offx, offy);
5084 15676083 });
5085
5086
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_layer_primitives(framebuf, 6);
5087
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(framebuf, true, 6);
5088
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 6);
5089
5090 15539765 bool any_dark = false;
5091
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5092 15676083 mapscr* base_scr = screen_handles[0].scr;
5093 15676083 any_dark |= is_dark(base_scr);
5094 15676083 });
5095
5096 // Handle low drawn darkness
5097
4/4
✓ Branch 0 taken 1269552 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 1025781 times.
✓ Branch 3 taken 243771 times.
15539765 if(get_qr(qr_NEW_DARKROOM) && any_dark)
5098 {
5099
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5100 250005 mapscr* base_scr = screen_handles[0].scr;
5101 250005 calc_darkroom_combos(base_scr, offx, offy + playing_field_offset);
5102 250005 calc_darkroom_ffcs(base_scr, 0, playing_field_offset);
5103 250005 });
5104
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 if(showhero)
5105
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 Hero.calc_darkroom_hero(0, -playing_field_offset);
5106
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 243771 times.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5107 250005 mapscr* base_scr = screen_handles[0].scr;
5108
2/2
✓ Branch 0 taken 245275 times.
✓ Branch 1 taken 4730 times.
250005 if (!is_dark(base_scr))
5109 {
5110 4730 offy += playing_field_offset;
5111 4730 rectfill(darkscr_bmp, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5112 4730 rectfill(darkscr_bmp_trans, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5113 4730 }
5114 250005 });
5115 243771 }
5116
5117 //Darkroom if under the subscreen
5118
6/6
✓ Branch 0 taken 1269552 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 823284 times.
✓ Branch 3 taken 446268 times.
✓ Branch 4 taken 231780 times.
✓ Branch 5 taken 591504 times.
15539765 if(get_qr(qr_NEW_DARKROOM) && get_qr(qr_NEWDARK_L6) && any_dark)
5119 {
5120
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5121
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5122
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231780 times.
231780 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5123 {
5124 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5125 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5126 }
5127
5128 231780 color_map = &trans_table2;
5129
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 231636 times.
231780 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5130 {
5131
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5132
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5133
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5134 144 }
5135 else
5136 {
5137
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5138
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5139 }
5140 231780 color_map = &trans_table;
5141
5142
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5143
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5144 231780 }
5145
5146
3/6
✓ Branch 0 taken 45626 times.
✓ Branch 1 taken 15494139 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45626 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
15539765 if (is_extended_height_mode() && lensclk && !FFCore.system_suspend[susptLENS])
5147 {
5148 draw_lens_over();
5149 --lensclk;
5150 }
5151
5152 // Draw some text on framebuf
5153
5154
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_clip_rect(framebuf,0,0,256,232);
5155
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 if(!get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5156
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(6);
5157
5158 // Draw the subscreen, without clipping
5159
2/2
✓ Branch 0 taken 6288381 times.
✓ Branch 1 taken 9251384 times.
15539765 if(get_qr(qr_SUBSCREENOVERSPRITES))
5160 {
5161
2/4
✓ Branch 0 taken 6288381 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6288381 times.
✗ Branch 3 not taken.
6288381 put_passive_subscr(framebuf, 0, 0, game->should_show_time(), sspUP);
5162
5163 // Draw primitives over subscren
5164
1/2
✓ Branch 0 taken 6288381 times.
✗ Branch 1 not taken.
6288381 do_primitives(framebuf, 7); //Layer '7' appears above subscreen if quest rule is set
5165 6288381 }
5166
5167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
15539765 if(get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5168 draw_msgstr(6);
5169
5170 // Handle high-drawn darkness
5171
6/6
✓ Branch 0 taken 1269552 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 446268 times.
✓ Branch 3 taken 823284 times.
✓ Branch 4 taken 11991 times.
✓ Branch 5 taken 434277 times.
15539765 if(get_qr(qr_NEW_DARKROOM) && !get_qr(qr_NEWDARK_L6) && any_dark)
5172 {
5173
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5174
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5175
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5176 {
5177 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5178 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5179 }
5180
5181 11991 color_map = &trans_table2;
5182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5183 {
5184 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5185 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5186 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5187 }
5188 else
5189 {
5190
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5191
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5192 }
5193 11991 color_map = &trans_table;
5194
5195
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5196
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5197 11991 }
5198
5199
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 7);
5200
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(7);
5201
5202
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_clip_rect(scrollbuf, 0, 0, scrollbuf->w, scrollbuf->h);
5203
3/4
✓ Branch 0 taken 14938100 times.
✓ Branch 1 taken 601665 times.
✓ Branch 2 taken 14938100 times.
✗ Branch 3 not taken.
15539765 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_POST_DRAW);
5204 76698313 }
5205
5206 // TODO: separate setting door data and drawing door
5207 28153 void put_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t type, bool redraw, bool even_walls)
5208 {
5209
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28153 times.
28153 if (type > 8) return;
5210
5211 28153 int32_t d=scr->door_combo_set;
5212
5213
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15611 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12542 times.
28153 switch(type)
5214 {
5215 case dt_wall:
5216 case dt_walk:
5217 if(!even_walls)
5218 break;
5219 [[fallthrough]];
5220 case dt_pass:
5221
3/4
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 11506 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1036 times.
12542 if(!get_qr(qr_REPLACEOPENDOORS) && !even_walls)
5222 1036 break;
5223 [[fallthrough]];
5224 case dt_lock:
5225 case dt_shut:
5226 case dt_boss:
5227 case dt_olck:
5228 case dt_osht:
5229 case dt_obos:
5230 case dt_bomb:
5231
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7259 times.
✓ Branch 2 taken 6784 times.
✓ Branch 3 taken 6362 times.
✓ Branch 4 taken 6712 times.
27117 switch(side)
5232 {
5233 case up:
5234 7259 scr->data[pos] = DoorComboSets[d].doorcombo_u[type][0];
5235 7259 scr->cset[pos] = DoorComboSets[d].doorcset_u[type][0];
5236 7259 scr->sflag[pos] = 0;
5237 7259 scr->data[pos+1] = DoorComboSets[d].doorcombo_u[type][1];
5238 7259 scr->cset[pos+1] = DoorComboSets[d].doorcset_u[type][1];
5239 7259 scr->sflag[pos+1] = 0;
5240 7259 scr->data[pos+16] = DoorComboSets[d].doorcombo_u[type][2];
5241 7259 scr->cset[pos+16] = DoorComboSets[d].doorcset_u[type][2];
5242 7259 scr->sflag[pos+16] = 0;
5243 7259 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_u[type][3];
5244 7259 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_u[type][3];
5245 7259 scr->sflag[pos+16+1] = 0;
5246
5247
2/2
✓ Branch 0 taken 5435 times.
✓ Branch 1 taken 1824 times.
7259 if(redraw)
5248 {
5249 3648 putcombo(dest,(pos&15)<<4,pos&0xF0,
5250 1824 DoorComboSets[d].doorcombo_u[type][0],
5251 1824 DoorComboSets[d].doorcset_u[type][0]);
5252 3648 putcombo(dest,((pos&15)<<4)+16,pos&0xF0,
5253 1824 DoorComboSets[d].doorcombo_u[type][1],
5254 1824 DoorComboSets[d].doorcset_u[type][1]);
5255 1824 }
5256
5257 7259 break;
5258
5259 case down:
5260 6784 scr->data[pos] = DoorComboSets[d].doorcombo_d[type][0];
5261 6784 scr->cset[pos] = DoorComboSets[d].doorcset_d[type][0];
5262 6784 scr->sflag[pos] = 0;
5263 6784 scr->data[pos+1] = DoorComboSets[d].doorcombo_d[type][1];
5264 6784 scr->cset[pos+1] = DoorComboSets[d].doorcset_d[type][1];
5265 6784 scr->sflag[pos+1] = 0;
5266 6784 scr->data[pos+16] = DoorComboSets[d].doorcombo_d[type][2];
5267 6784 scr->cset[pos+16] = DoorComboSets[d].doorcset_d[type][2];
5268 6784 scr->sflag[pos+16] = 0;
5269 6784 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_d[type][3];
5270 6784 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_d[type][3];
5271 6784 scr->sflag[pos+16+1] = 0;
5272
5273
2/2
✓ Branch 0 taken 5463 times.
✓ Branch 1 taken 1321 times.
6784 if(redraw)
5274 {
5275 2642 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5276 1321 DoorComboSets[d].doorcombo_d[type][2],
5277 1321 DoorComboSets[d].doorcset_d[type][2]);
5278 2642 putcombo(dest,((pos&15)<<4)+16,(pos&0xF0)+16,
5279 1321 DoorComboSets[d].doorcombo_d[type][3],
5280 1321 DoorComboSets[d].doorcset_d[type][3]);
5281 1321 }
5282
5283 6784 break;
5284
5285 case left:
5286 6362 scr->data[pos] = DoorComboSets[d].doorcombo_l[type][0];
5287 6362 scr->cset[pos] = DoorComboSets[d].doorcset_l[type][0];
5288 6362 scr->sflag[pos] = 0;
5289 6362 scr->data[pos+1] = DoorComboSets[d].doorcombo_l[type][1];
5290 6362 scr->cset[pos+1] = DoorComboSets[d].doorcset_l[type][1];
5291 6362 scr->sflag[pos+1] = 0;
5292 6362 scr->data[pos+16] = DoorComboSets[d].doorcombo_l[type][2];
5293 6362 scr->cset[pos+16] = DoorComboSets[d].doorcset_l[type][2];
5294 6362 scr->sflag[pos+16] = 0;
5295 6362 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_l[type][3];
5296 6362 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_l[type][3];
5297 6362 scr->sflag[pos+16+1] = 0;
5298 6362 scr->data[pos+32] = DoorComboSets[d].doorcombo_l[type][4];
5299 6362 scr->cset[pos+32] = DoorComboSets[d].doorcset_l[type][4];
5300 6362 scr->sflag[pos+32] = 0;
5301 6362 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_l[type][5];
5302 6362 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_l[type][5];
5303 6362 scr->sflag[pos+32+1] = 0;
5304
5305
2/2
✓ Branch 0 taken 4873 times.
✓ Branch 1 taken 1489 times.
6362 if(redraw)
5306 {
5307 2978 putcombo(dest,(pos&15)<<4,pos&0xF0,
5308 1489 DoorComboSets[d].doorcombo_l[type][0],
5309 1489 DoorComboSets[d].doorcset_l[type][0]);
5310 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5311 1489 DoorComboSets[d].doorcombo_l[type][2],
5312 1489 DoorComboSets[d].doorcset_l[type][2]);
5313 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5314 1489 DoorComboSets[d].doorcombo_l[type][4],
5315 1489 DoorComboSets[d].doorcset_l[type][4]);
5316 1489 }
5317
5318 6362 break;
5319
5320 case right:
5321 6712 scr->data[pos] = DoorComboSets[d].doorcombo_r[type][0];
5322 6712 scr->cset[pos] = DoorComboSets[d].doorcset_r[type][0];
5323 6712 scr->sflag[pos] = 0;
5324 6712 scr->data[pos+1] = DoorComboSets[d].doorcombo_r[type][1];
5325 6712 scr->cset[pos+1] = DoorComboSets[d].doorcset_r[type][1];
5326 6712 scr->sflag[pos+1] = 0;
5327 6712 scr->data[pos+16] = DoorComboSets[d].doorcombo_r[type][2];
5328 6712 scr->cset[pos+16] = DoorComboSets[d].doorcset_r[type][2];
5329 6712 scr->sflag[pos+16] = 0;
5330 6712 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_r[type][3];
5331 6712 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_r[type][3];
5332 6712 scr->sflag[pos+16+1] = 0;
5333 6712 scr->data[pos+32] = DoorComboSets[d].doorcombo_r[type][4];
5334 6712 scr->cset[pos+32] = DoorComboSets[d].doorcset_r[type][4];
5335 6712 scr->sflag[pos+32] = 0;
5336 6712 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_r[type][5];
5337 6712 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_r[type][5];
5338 6712 scr->sflag[pos+32+1] = 0;
5339
5340
2/2
✓ Branch 0 taken 5058 times.
✓ Branch 1 taken 1654 times.
6712 if(redraw)
5341 {
5342 3308 putcombo(dest,(pos&15)<<4,pos&0xF0,
5343 1654 DoorComboSets[d].doorcombo_r[type][0],
5344 1654 DoorComboSets[d].doorcset_r[type][0]);
5345 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5346 1654 DoorComboSets[d].doorcombo_r[type][2],
5347 1654 DoorComboSets[d].doorcset_r[type][2]);
5348 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5349 1654 DoorComboSets[d].doorcombo_r[type][4],
5350 1654 DoorComboSets[d].doorcset_r[type][4]);
5351 1654 }
5352
5353 6712 break;
5354 }
5355
5356 27117 break;
5357
5358 default:
5359 break;
5360 }
5361 28153 }
5362
5363 706556 static void over_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t offx, int32_t offy)
5364 {
5365 706556 int32_t door_combo_set = scr->door_combo_set;
5366 706556 int32_t x = (pos&15)<<4;
5367 706556 int32_t y = (pos&0xF0);
5368 706556 int32_t d = door_combo_set;
5369 706556 x += offx;
5370 706556 y += offy;
5371
5372
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 161136 times.
✓ Branch 2 taken 179643 times.
✓ Branch 3 taken 196353 times.
✓ Branch 4 taken 169424 times.
706556 switch(side)
5373 {
5374 case up:
5375 322272 overcombo2(dest,x,y,
5376 161136 DoorComboSets[d].bombdoorcombo_u[0],
5377 161136 DoorComboSets[d].bombdoorcset_u[0]);
5378 322272 overcombo2(dest,x+16,y,
5379 161136 DoorComboSets[d].bombdoorcombo_u[1],
5380 161136 DoorComboSets[d].bombdoorcset_u[1]);
5381 161136 break;
5382
5383 case down:
5384 359286 overcombo2(dest,x,y,
5385 179643 DoorComboSets[d].bombdoorcombo_d[0],
5386 179643 DoorComboSets[d].bombdoorcset_d[0]);
5387 359286 overcombo2(dest,x+16,y,
5388 179643 DoorComboSets[d].bombdoorcombo_d[1],
5389 179643 DoorComboSets[d].bombdoorcset_d[1]);
5390 179643 break;
5391
5392 case left:
5393 392706 overcombo2(dest,x,y,
5394 196353 DoorComboSets[d].bombdoorcombo_l[0],
5395 196353 DoorComboSets[d].bombdoorcset_l[0]);
5396 392706 overcombo2(dest,x,y+16,
5397 196353 DoorComboSets[d].bombdoorcombo_l[1],
5398 196353 DoorComboSets[d].bombdoorcset_l[1]);
5399 392706 overcombo2(dest,x,y+16,
5400 196353 DoorComboSets[d].bombdoorcombo_l[2],
5401 196353 DoorComboSets[d].bombdoorcset_l[2]);
5402 196353 break;
5403
5404 case right:
5405 338848 overcombo2(dest,x,y,
5406 169424 DoorComboSets[d].bombdoorcombo_r[0],
5407 169424 DoorComboSets[d].bombdoorcset_r[0]);
5408 338848 overcombo2(dest,x,y+16,
5409 169424 DoorComboSets[d].bombdoorcombo_r[1],
5410 169424 DoorComboSets[d].bombdoorcset_r[1]);
5411 338848 overcombo2(dest,x,y+16,
5412 169424 DoorComboSets[d].bombdoorcombo_r[2],
5413 169424 DoorComboSets[d].bombdoorcset_r[2]);
5414 169424 break;
5415 }
5416 706556 }
5417
5418 47568 void update_door(mapscr* scr, int32_t side, int32_t door, bool even_walls)
5419 {
5420
7/8
✓ Branch 0 taken 47460 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 47460 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22925 times.
✓ Branch 5 taken 24535 times.
✓ Branch 6 taken 530 times.
✓ Branch 7 taken 22395 times.
47568 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5421 25173 return;
5422
5423 int32_t doortype;
5424
5425
10/12
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 655 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12492 times.
✓ Branch 5 taken 910 times.
✓ Branch 6 taken 1553 times.
✓ Branch 7 taken 3192 times.
✓ Branch 8 taken 1694 times.
✓ Branch 9 taken 172 times.
✓ Branch 10 taken 67 times.
✓ Branch 11 taken 1138 times.
22395 switch(door)
5426 {
5427 case dWALL:
5428 doortype=dt_wall;
5429 break;
5430
5431 case dWALK:
5432 doortype=dt_walk;
5433 break;
5434
5435 case dOPEN:
5436 12492 doortype=dt_pass;
5437 12492 break;
5438
5439 case dLOCKED:
5440 910 doortype=dt_lock;
5441 910 break;
5442
5443 case dUNLOCKED:
5444 1553 doortype=dt_olck;
5445 1553 break;
5446
5447 case dSHUTTER:
5448
3/4
✓ Branch 0 taken 2783 times.
✓ Branch 1 taken 409 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2783 times.
3192 if(screenscrolling && ((HeroDir()^1)==side))
5449 {
5450 doortype=dt_osht;
5451 get_screen_state(scr->screen).open_doors = -4;
5452 break;
5453 }
5454
5455 [[fallthrough]];
5456 case d1WAYSHUTTER:
5457 3714 doortype=dt_shut;
5458 3714 break;
5459
5460 case dOPENSHUTTER:
5461 1694 doortype=dt_osht;
5462 1694 break;
5463
5464 case dBOSS:
5465 172 doortype=dt_boss;
5466 172 break;
5467
5468 case dOPENBOSS:
5469 67 doortype=dt_obos;
5470 67 break;
5471
5472 case dBOMBED:
5473 1138 doortype=dt_bomb;
5474 1138 break;
5475
5476 default:
5477 655 return;
5478 }
5479
5480
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5629 times.
✓ Branch 2 taken 5770 times.
✓ Branch 3 taken 5111 times.
✓ Branch 4 taken 5230 times.
21740 switch(side)
5481 {
5482 case up:
5483 5629 put_door(scr,nullptr,7,side,doortype,false,even_walls);
5484 5629 break;
5485
5486 case down:
5487 5770 put_door(scr,nullptr,151,side,doortype,false,even_walls);
5488 5770 break;
5489
5490 case left:
5491 5111 put_door(scr,nullptr,64,side,doortype,false,even_walls);
5492 5111 break;
5493
5494 case right:
5495 5230 put_door(scr,nullptr,78,side,doortype,false,even_walls);
5496 5230 break;
5497 }
5498 47568 }
5499
5500 6504 void putdoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t door, bool redraw, bool even_walls)
5501 {
5502 /*
5503 #define dWALL 0 // 000 0
5504 #define dBOMB 6 // 011 0
5505 #define 8 // 100 0
5506 enum {dt_pass=0, dt_lock, dt_shut, dt_boss, dt_olck, dt_osht, dt_obos, dt_wall, dt_bomb, dt_walk, dt_max};
5507 */
5508
5509
7/8
✓ Branch 0 taken 6504 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6500 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6417 times.
✓ Branch 5 taken 83 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 6409 times.
6504 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5510 91 return;
5511
5512 int32_t doortype;
5513
5514
8/12
✓ Branch 0 taken 227 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 362 times.
✓ Branch 7 taken 1530 times.
✓ Branch 8 taken 3958 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 51 times.
✓ Branch 11 taken 231 times.
6413 switch(door)
5515 {
5516 case dWALL:
5517 doortype=dt_wall;
5518 break;
5519
5520 case dWALK:
5521 doortype=dt_walk;
5522 break;
5523
5524 case dOPEN:
5525 50 doortype=dt_pass;
5526 50 break;
5527
5528 case dLOCKED:
5529 doortype=dt_lock;
5530 break;
5531
5532 case dUNLOCKED:
5533 362 doortype=dt_olck;
5534 362 break;
5535
5536 case dSHUTTER:
5537
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1530 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1530 if(screenscrolling && ((HeroDir()^1)==side))
5538 {
5539 doortype=dt_osht;
5540 get_screen_state(cur_screen).open_doors = -4;
5541 break;
5542 }
5543
5544 [[fallthrough]];
5545 case d1WAYSHUTTER:
5546 1757 doortype=dt_shut;
5547 1757 break;
5548
5549 case dOPENSHUTTER:
5550 3958 doortype=dt_osht;
5551 3958 break;
5552
5553 case dBOSS:
5554 4 doortype=dt_boss;
5555 4 break;
5556
5557 case dOPENBOSS:
5558 51 doortype=dt_obos;
5559 51 break;
5560
5561 case dBOMBED:
5562 231 doortype=dt_bomb;
5563 231 break;
5564
5565 default:
5566 return;
5567 }
5568
5569
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1860 times.
✓ Branch 2 taken 1357 times.
✓ Branch 3 taken 1514 times.
✓ Branch 4 taken 1682 times.
6413 switch(side)
5570 {
5571 case up:
5572
2/2
✓ Branch 0 taken 1791 times.
✓ Branch 1 taken 69 times.
1860 switch(door)
5573 {
5574 case dBOMBED:
5575
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
138 if(redraw)
5576 {
5577 69 over_door(scr,dest,39,side,0,0);
5578 69 }
5579 [[fallthrough]];
5580 default:
5581 1860 put_door(scr,dest,7,side,doortype,redraw, even_walls);
5582 1860 break;
5583 }
5584
5585 1860 break;
5586
5587 case down:
5588
2/2
✓ Branch 0 taken 1318 times.
✓ Branch 1 taken 39 times.
1357 switch(door)
5589 {
5590 case dBOMBED:
5591
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
78 if(redraw)
5592 {
5593 39 over_door(scr,dest,135,side,0,0);
5594 39 }
5595 [[fallthrough]];
5596 default:
5597 1357 put_door(scr,dest,151,side,doortype,redraw, even_walls);
5598 1357 break;
5599 }
5600
5601 1357 break;
5602
5603 case left:
5604
2/2
✓ Branch 0 taken 1463 times.
✓ Branch 1 taken 51 times.
1514 switch(door)
5605 {
5606 case dBOMBED:
5607
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
102 if(redraw)
5608 {
5609 51 over_door(scr,dest,66,side,0,0);
5610 51 }
5611 [[fallthrough]];
5612 default:
5613 1514 put_door(scr,dest,64,side,doortype,redraw, even_walls);
5614 1514 break;
5615 }
5616
5617 1514 break;
5618
5619 case right:
5620
2/2
✓ Branch 0 taken 1610 times.
✓ Branch 1 taken 72 times.
1682 switch(door)
5621 {
5622 case dBOMBED:
5623
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
144 if(redraw)
5624 {
5625 72 over_door(scr,dest,77,side,0,0);
5626 72 }
5627 [[fallthrough]];
5628 default:
5629 1682 put_door(scr,dest,78,side,doortype,redraw, even_walls);
5630 1682 break;
5631 }
5632
5633 1682 break;
5634 }
5635 6504 }
5636
5637 586 void putcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5638 {
5639
1/2
✓ Branch 0 taken 586 times.
✗ Branch 1 not taken.
586 if(combo!=0)
5640 {
5641 586 putcombo(dest,x, y, combo, cset);
5642 586 }
5643 586 }
5644
5645 293 void overcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5646 {
5647
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 74 times.
293 if(combo!=0)
5648 {
5649 219 overcombo(dest,x, y, combo, cset);
5650 219 }
5651 293 }
5652
5653 125 void showbombeddoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t offx, int32_t offy)
5654 {
5655 125 int32_t d = scr->door_combo_set;
5656
5657
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 37 times.
125 switch(side)
5658 {
5659 case up:
5660 86 putcombo_not_zero(dest,((7&15)<<4) + offx,(7&0xF0) + offy,
5661 43 DoorComboSets[d].doorcombo_u[dt_bomb][0],
5662 43 DoorComboSets[d].doorcset_u[dt_bomb][0]);
5663 86 putcombo_not_zero(dest,((8&15)<<4) + offx,(8&0xF0) + offy,
5664 43 DoorComboSets[d].doorcombo_u[dt_bomb][1],
5665 43 DoorComboSets[d].doorcset_u[dt_bomb][1]);
5666 86 putcombo_not_zero(dest,((23&15)<<4) + offx,(23&0xF0) + offy,
5667 43 DoorComboSets[d].doorcombo_u[dt_bomb][2],
5668 43 DoorComboSets[d].doorcset_u[dt_bomb][2]);
5669 86 putcombo_not_zero(dest,((24&15)<<4) + offx,(24&0xF0) + offy,
5670 43 DoorComboSets[d].doorcombo_u[dt_bomb][3],
5671 43 DoorComboSets[d].doorcset_u[dt_bomb][3]);
5672 86 overcombo_not_zero(dest,((39&15)<<4) + offx,(39&0xF0) + offy,
5673 43 DoorComboSets[d].bombdoorcombo_u[0],
5674 43 DoorComboSets[d].bombdoorcset_u[0]);
5675 86 overcombo_not_zero(dest,((40&15)<<4) + offx,(40&0xF0) + offy,
5676 43 DoorComboSets[d].bombdoorcombo_u[1],
5677 43 DoorComboSets[d].bombdoorcset_u[1]);
5678 43 break;
5679
5680 case down:
5681 78 putcombo_not_zero(dest,((151&15)<<4) + offx,(151&0xF0) + offy,
5682 39 DoorComboSets[d].doorcombo_d[dt_bomb][0],
5683 39 DoorComboSets[d].doorcset_d[dt_bomb][0]);
5684 78 putcombo_not_zero(dest,((152&15)<<4) + offx,(152&0xF0) + offy,
5685 39 DoorComboSets[d].doorcombo_d[dt_bomb][1],
5686 39 DoorComboSets[d].doorcset_d[dt_bomb][1]);
5687 78 putcombo_not_zero(dest,((167&15)<<4) + offx,(167&0xF0) + offy,
5688 39 DoorComboSets[d].doorcombo_d[dt_bomb][2],
5689 39 DoorComboSets[d].doorcset_d[dt_bomb][2]);
5690 78 putcombo_not_zero(dest,((168&15)<<4) + offx,(168&0xF0) + offy,
5691 39 DoorComboSets[d].doorcombo_d[dt_bomb][3],
5692 39 DoorComboSets[d].doorcset_d[dt_bomb][3]);
5693 78 overcombo_not_zero(dest,((135&15)<<4) + offx,(135&0xF0) + offy,
5694 39 DoorComboSets[d].bombdoorcombo_d[0],
5695 39 DoorComboSets[d].bombdoorcset_d[0]);
5696 78 overcombo_not_zero(dest,((136&15)<<4) + offx,(136&0xF0) + offy,
5697 39 DoorComboSets[d].bombdoorcombo_d[1],
5698 39 DoorComboSets[d].bombdoorcset_d[1]);
5699 39 break;
5700
5701 case left:
5702 12 putcombo_not_zero(dest,((64&15)<<4) + offx,(64&0xF0) + offy,
5703 6 DoorComboSets[d].doorcombo_l[dt_bomb][0],
5704 6 DoorComboSets[d].doorcset_l[dt_bomb][0]);
5705 12 putcombo_not_zero(dest,((65&15)<<4) + offx,(65&0xF0) + offy,
5706 6 DoorComboSets[d].doorcombo_l[dt_bomb][1],
5707 6 DoorComboSets[d].doorcset_l[dt_bomb][1]);
5708 12 putcombo_not_zero(dest,((80&15)<<4) + offx,(80&0xF0) + offy,
5709 6 DoorComboSets[d].doorcombo_l[dt_bomb][2],
5710 6 DoorComboSets[d].doorcset_l[dt_bomb][2]);
5711 12 putcombo_not_zero(dest,((81&15)<<4) + offx,(81&0xF0) + offy,
5712 6 DoorComboSets[d].doorcombo_l[dt_bomb][3],
5713 6 DoorComboSets[d].doorcset_l[dt_bomb][3]);
5714 12 putcombo_not_zero(dest,((96&15)<<4) + offx,(96&0xF0) + offy,
5715 6 DoorComboSets[d].doorcombo_l[dt_bomb][4],
5716 6 DoorComboSets[d].doorcset_l[dt_bomb][4]);
5717 12 putcombo_not_zero(dest,((97&15)<<4) + offx,(97&0xF0) + offy,
5718 6 DoorComboSets[d].doorcombo_l[dt_bomb][5],
5719 6 DoorComboSets[d].doorcset_l[dt_bomb][5]);
5720 12 overcombo_not_zero(dest,((66&15)<<4) + offx,(66&0xF0) + offy,
5721 6 DoorComboSets[d].bombdoorcombo_l[0],
5722 6 DoorComboSets[d].bombdoorcset_l[0]);
5723 12 overcombo_not_zero(dest,((82&15)<<4) + offx,(82&0xF0) + offy,
5724 6 DoorComboSets[d].bombdoorcombo_l[1],
5725 6 DoorComboSets[d].bombdoorcset_l[1]);
5726 12 overcombo_not_zero(dest,((98&15)<<4) + offx,(98&0xF0) + offy,
5727 6 DoorComboSets[d].bombdoorcombo_l[2],
5728 6 DoorComboSets[d].bombdoorcset_l[2]);
5729 6 break;
5730
5731 case right:
5732 74 putcombo_not_zero(dest,((78&15)<<4) + offx,(78&0xF0) + offy,
5733 37 DoorComboSets[d].doorcombo_r[dt_bomb][0],
5734 37 DoorComboSets[d].doorcset_r[dt_bomb][0]);
5735 74 putcombo_not_zero(dest,((79&15)<<4) + offx,(79&0xF0) + offy,
5736 37 DoorComboSets[d].doorcombo_r[dt_bomb][1],
5737 37 DoorComboSets[d].doorcset_r[dt_bomb][1]);
5738 74 putcombo_not_zero(dest,((94&15)<<4) + offx,(94&0xF0) + offy,
5739 37 DoorComboSets[d].doorcombo_r[dt_bomb][2],
5740 37 DoorComboSets[d].doorcset_r[dt_bomb][2]);
5741 74 putcombo_not_zero(dest,((95&15)<<4) + offx,(95&0xF0) + offy,
5742 37 DoorComboSets[d].doorcombo_r[dt_bomb][3],
5743 37 DoorComboSets[d].doorcset_r[dt_bomb][3]);
5744 74 putcombo_not_zero(dest,((110&15)<<4) + offx,(110&0xF0) + offy,
5745 37 DoorComboSets[d].doorcombo_r[dt_bomb][4],
5746 37 DoorComboSets[d].doorcset_r[dt_bomb][4]);
5747 74 putcombo_not_zero(dest,((111&15)<<4) + offx,(111&0xF0) + offy,
5748 37 DoorComboSets[d].doorcombo_r[dt_bomb][5],
5749 37 DoorComboSets[d].doorcset_r[dt_bomb][5]);
5750 74 overcombo_not_zero(dest,((77&15)<<4) + offx,(77&0xF0) + offy,
5751 37 DoorComboSets[d].bombdoorcombo_r[0],
5752 37 DoorComboSets[d].bombdoorcset_r[0]);
5753 74 overcombo_not_zero(dest,((93&15)<<4) + offx,(93&0xF0) + offy,
5754 37 DoorComboSets[d].bombdoorcombo_r[1],
5755 37 DoorComboSets[d].bombdoorcset_r[1]);
5756 74 overcombo_not_zero(dest,((109&15)<<4) + offx,(109&0xF0) + offy,
5757 37 DoorComboSets[d].bombdoorcombo_r[2],
5758 37 DoorComboSets[d].bombdoorcset_r[2]);
5759 37 break;
5760 }
5761 125 }
5762
5763 5357371 void openshutters(mapscr* scr)
5764 {
5765 5357371 bool opened_door = false;
5766
2/2
✓ Branch 0 taken 5357371 times.
✓ Branch 1 taken 21429484 times.
26786855 for(int32_t i=0; i<4; i++)
5767
2/2
✓ Branch 0 taken 21425526 times.
✓ Branch 1 taken 3958 times.
21433442 if(scr->door[i]==dSHUTTER)
5768 {
5769 3958 putdoor(scr, scrollbuf, i, dOPENSHUTTER);
5770 3958 scr->door[i]=dOPENSHUTTER;
5771 3958 opened_door = true;
5772 3958 }
5773
5774 5357371 auto& combo_cache = combo_caches::shutter;
5775 2070389927 for_every_combo_in_screen(create_screen_handles(scr), [&](const auto& handle) {
5776
3/4
✓ Branch 0 taken 2063421881 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1610668 times.
✗ Branch 3 not taken.
2065032556 if (!combo_cache.minis[handle.data()].shutter)
5777 2065032549 return;
5778
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
5779 7 return trig.trigger_flags.get(TRIGFLAG_SHUTTER);
5780 });
5781 2065032556 });
5782
5783
2/2
✓ Branch 0 taken 5354640 times.
✓ Branch 1 taken 2731 times.
5357371 if(opened_door)
5784 2731 sfx(WAV_DOOR);
5785 5357371 }
5786
5787 15116782 void clear_darkroom_bitmaps()
5788 {
5789 15116782 clear_to_color(darkscr_bmp, game->get_darkscr_color());
5790 15116782 clear_to_color(darkscr_bmp_trans, game->get_darkscr_color());
5791 15116782 }
5792
5793 16031111 bool is_dark(const mapscr* scr)
5794 {
5795 16031111 bool dark = scr->flags&fDARK;
5796
2/2
✓ Branch 0 taken 3722 times.
✓ Branch 1 taken 16027389 times.
16031111 if (region_is_lit) return !dark;
5797 16027389 return dark;
5798 16031111 }
5799
5800 39226 bool scrolling_is_dark(const mapscr* scr)
5801 {
5802 39226 bool dark = scr->flags&fDARK;
5803
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 39224 times.
39226 if (scrolling_region_is_lit) return !dark;
5804 39224 return dark;
5805 39226 }
5806
5807 36758 bool is_any_dark()
5808 {
5809 36758 bool dark = false;
5810 74772 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
5811 38014 dark |= (bool)(is_dark(scr));
5812 38014 });
5813 36758 return dark;
5814 }
5815
5816
3/4
✓ Branch 0 taken 2898 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2484 times.
✓ Branch 3 taken 414 times.
2898 static mapscr prev_origin_scrs[7];
5817 414 static std::set<int> loadscr_ffc_script_ids_to_remove;
5818
5819 static void handle_screen_overlay(const std::vector<mapscr*>& screens)
5820 {
5821 mapscr* base_scr = screens[0];
5822 mapscr* previous_scr = &prev_origin_scrs[0];
5823
5824 for (int i = 0; i < 176; i++)
5825 {
5826 if (base_scr->data[i] == 0)
5827 {
5828 base_scr->data[i] = previous_scr->data[i];
5829 base_scr->sflag[i] = previous_scr->sflag[i];
5830 base_scr->cset[i] = previous_scr->cset[i];
5831 }
5832 }
5833
5834 for (int i = 0; i < 6; i++)
5835 {
5836 if (previous_scr->layermap[i] > 0 && base_scr->layermap[i] > 0)
5837 {
5838 int lm = (base_scr->layermap[i]-1)*MAPSCRS+base_scr->layerscreen[i];
5839 int fm = (previous_scr->layermap[i]-1)*MAPSCRS+previous_scr->layerscreen[i];
5840
5841 for (int j = 0; j < 176; j++)
5842 {
5843 if (TheMaps[lm].data[j] == 0)
5844 {
5845 TheMaps[lm].data[j] = TheMaps[fm].data[j];
5846 TheMaps[lm].sflag[j] = TheMaps[fm].sflag[j];
5847 TheMaps[lm].cset[j] = TheMaps[fm].cset[j];
5848 }
5849 }
5850 }
5851 }
5852
5853 for (int i = 1; i <= 6; i++)
5854 {
5855 mapscr* scr = screens[i];
5856 previous_scr = &prev_origin_scrs[i];
5857
5858 if (scr->layermap[i] > 0)
5859 {
5860 for (int y = 0; y < 11; y++)
5861 {
5862 for (int x = 0; x < 16; x++)
5863 {
5864 int c = y*16+x;
5865
5866 if (scr->data[c]==0)
5867 {
5868 scr->data[c] = previous_scr->data[c];
5869 scr->sflag[c] = previous_scr->sflag[c];
5870 scr->cset[c] = previous_scr->cset[c];
5871 }
5872 }
5873 }
5874 }
5875 }
5876 }
5877
5878 37098 static void load_a_screen_and_layers_init(int dmap, int screen, int ldir, bool screen_overlay, bool ffc_overlay)
5879 {
5880 37098 std::vector<mapscr*> screens;
5881
5882
1/2
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
37098 const mapscr* source = get_canonical_scr(cur_map, screen);
5883
2/4
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37098 times.
✗ Branch 3 not taken.
37098 mapscr* base_scr = new mapscr(*source);
5884 37098 temporary_screens[screen*7] = base_scr;
5885
1/2
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
37098 screens.push_back(base_scr);
5886
5887 37098 base_scr->valid |= mVALID; // layer 0 is always valid
5888
5889
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35854 times.
37098 if (screen == cur_screen)
5890 35854 origin_scr = base_scr;
5891
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35854 times.
37098 if (screen == Hero.current_screen)
5892 35854 hero_scr = prev_hero_scr = base_scr;
5893
5894
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 36979 times.
37098 if (source->script > 0)
5895
1/2
✓ Branch 0 taken 119 times.
✗ Branch 1 not taken.
119 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
5896
5897
2/2
✓ Branch 0 taken 37098 times.
✓ Branch 1 taken 222588 times.
259686 for (int i = 0; i < 6; i++)
5898 {
5899
2/2
✓ Branch 0 taken 173511 times.
✓ Branch 1 taken 49077 times.
222588 if(source->layermap[i]>0)
5900 {
5901
3/6
✓ Branch 0 taken 49077 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49077 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 49077 times.
✗ Branch 5 not taken.
49077 mapscr* layer_scr = new mapscr(*get_canonical_scr(source->layermap[i]-1, source->layerscreen[i]));
5902 49077 layer_scr->map = cur_map;
5903 49077 layer_scr->screen = screen;
5904 49077 layer_scr->valid |= mVALID;
5905
1/2
✓ Branch 0 taken 49077 times.
✗ Branch 1 not taken.
49077 screens.push_back(layer_scr);
5906 49077 }
5907 else
5908 {
5909
2/4
✓ Branch 0 taken 173511 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 173511 times.
✗ Branch 3 not taken.
173511 mapscr* layer_scr = new mapscr();
5910 173511 layer_scr->map = cur_map;
5911 173511 layer_scr->screen = screen;
5912
1/2
✓ Branch 0 taken 173511 times.
✗ Branch 1 not taken.
173511 screens.push_back(layer_scr);
5913 }
5914 222588 temporary_screens[screen*7+i+1] = screens[i+1];
5915 222588 }
5916
5917
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37098 times.
37098 if (screen_overlay)
5918 handle_screen_overlay(screens);
5919
5920
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 36954 times.
37098 if (ffc_overlay)
5921 {
5922 144 mapscr* previous_scr = &prev_origin_scrs[0];
5923
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 int num_ffcs = previous_scr->numFFC();
5924
2/2
✓ Branch 0 taken 4608 times.
✓ Branch 1 taken 144 times.
4752 for (int i = 0; i < num_ffcs; i++)
5925 {
5926
2/2
✓ Branch 0 taken 4334 times.
✓ Branch 1 taken 274 times.
4608 if ((previous_scr->ffcs[i].flags&ffc_carryover))
5927 {
5928
2/4
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 274 times.
✗ Branch 3 not taken.
274 auto& ffc = base_scr->getFFC(i) = previous_scr->ffcs[i];
5929 274 ffc.screen_spawned = screen;
5930
5931
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + i;
5932
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 loadscr_ffc_script_ids_to_remove.erase(ffc_id);
5933
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 274 times.
274 if (previous_scr->ffcs[i].flags&ffc_scriptreset)
5934 {
5935 FFCore.reset_script_engine_data(ScriptType::FFC, ffc_id);
5936 }
5937 274 }
5938 4608 }
5939 144 }
5940
5941
1/2
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
1141914 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
5942
1/2
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
37098 int num_ffcs = base_scr->numFFC();
5943
2/2
✓ Branch 0 taken 1104816 times.
✓ Branch 1 taken 37098 times.
1141914 for (word i = 0; i < num_ffcs; i++)
5944 {
5945 1104816 base_scr->ffcs[i].screen_spawned = screen;
5946
1/2
✓ Branch 0 taken 1104816 times.
✗ Branch 1 not taken.
1104816 base_scr->ffcs[i].x += offx;
5947
1/2
✓ Branch 0 taken 1104816 times.
✗ Branch 1 not taken.
1104816 base_scr->ffcs[i].y += offy;
5948 1104816 }
5949 37098 }
5950
5951 37098 static void load_a_screen_and_layers_post(int dmap, int screen, int ldir)
5952 {
5953 37098 mapscr* base_scr = get_scr(screen);
5954 37098 int mi = mapind(cur_map, screen);
5955
5956 // Apply perm secrets, if applicable.
5957
2/2
✓ Branch 0 taken 11520 times.
✓ Branch 1 taken 25578 times.
37098 if (canPermSecret(dmap, screen))
5958 {
5959
2/2
✓ Branch 0 taken 23053 times.
✓ Branch 1 taken 2525 times.
25578 if(game->maps[mi] & mSECRET) // if special stuff done before
5960 {
5961 2525 reveal_hidden_stairs(base_scr, screen, false);
5962 2525 trigger_secrets_for_screen(TriggerSource::SecretsScreenState, base_scr, false);
5963 2525 }
5964
2/2
✓ Branch 0 taken 25575 times.
✓ Branch 1 taken 3 times.
25578 if(game->maps[mi] & mLIGHTBEAM) // if special stuff done before
5965 {
5966
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (int layer = 0; layer <= 6; layer++)
5967 {
5968 21 mapscr* layer_scr = get_scr_layer(screen, layer);
5969
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 21 times.
3717 for (int pos = 0; pos < 176; pos++)
5970 {
5971 3696 newcombo const* cmb = &combobuf[layer_scr->data[pos]];
5972
2/2
✓ Branch 0 taken 3693 times.
✓ Branch 1 taken 3 times.
3696 if(cmb->type == cLIGHTTARGET)
5973 {
5974
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(cmb->usrflags&cflag1)) //Unlit version
5975 {
5976 3 layer_scr->data[pos] += 1;
5977 3 }
5978 3 }
5979 3696 }
5980 21 }
5981 3 }
5982 25578 }
5983
5984 37098 auto screen_handles = create_screen_handles(base_scr);
5985
5986 37098 int destlvl = DMaps[dmap].level;
5987 37098 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
5988 37098 toggle_gswitches_load(screen_handles);
5989
5990 37098 bool should_check_for_state_things = (screen < 0x80);
5991
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 36191 times.
37098 if (should_check_for_state_things)
5992 {
5993
2/2
✓ Branch 0 taken 35819 times.
✓ Branch 1 taken 372 times.
36191 if (game->maps[mi]&mLOCKBLOCK)
5994 372 remove_lockblocks(screen_handles);
5995
2/2
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 58 times.
36191 if (game->maps[mi]&mBOSSLOCKBLOCK)
5996 58 remove_bosslockblocks(screen_handles);
5997
2/2
✓ Branch 0 taken 36035 times.
✓ Branch 1 taken 156 times.
36191 if (game->maps[mi]&mCHEST)
5998 156 remove_chests(screen_handles);
5999
1/2
✓ Branch 0 taken 36191 times.
✗ Branch 1 not taken.
36191 if (game->maps[mi]&mLOCKEDCHEST)
6000 remove_lockedchests(screen_handles);
6001
2/2
✓ Branch 0 taken 36180 times.
✓ Branch 1 taken 11 times.
36191 if (game->maps[mi]&mBOSSCHEST)
6002 11 remove_bosschests(screen_handles);
6003
6004 36191 clear_xdoors_mi(screen_handles, mi, true);
6005 36191 clear_xstatecombos_mi(screen_handles, mi, true);
6006 36191 }
6007
6008 // check doors
6009
2/2
✓ Branch 0 taken 25577 times.
✓ Branch 1 taken 11521 times.
37098 if (isdungeon(dmap, screen))
6010 {
6011
2/2
✓ Branch 0 taken 46084 times.
✓ Branch 1 taken 11521 times.
57605 for(int32_t i=0; i<4; i++)
6012 {
6013 46084 int32_t door=base_scr->door[i];
6014
6015
5/5
✓ Branch 0 taken 5303 times.
✓ Branch 1 taken 36475 times.
✓ Branch 2 taken 2372 times.
✓ Branch 3 taken 230 times.
✓ Branch 4 taken 1704 times.
46084 switch(door)
6016 {
6017 case d1WAYSHUTTER:
6018 case dSHUTTER:
6019
3/4
✓ Branch 0 taken 1694 times.
✓ Branch 1 taken 3609 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1694 times.
5303 if ((ldir^1)==i && screen == Hero.current_screen)
6020 {
6021 1694 base_scr->door[i]=dOPENSHUTTER;
6022 1694 }
6023
6024 5303 get_screen_state(screen).open_doors = -4;
6025 5303 break;
6026
6027 case dLOCKED:
6028
3/4
✓ Branch 0 taken 2372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1473 times.
✓ Branch 3 taken 899 times.
2372 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6029 {
6030 1473 base_scr->door[i]=dUNLOCKED;
6031 1473 }
6032
6033 2372 break;
6034
6035 case dBOSS:
6036
3/4
✓ Branch 0 taken 230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 168 times.
230 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6037 {
6038 62 base_scr->door[i]=dOPENBOSS;
6039 62 }
6040
6041 230 break;
6042
6043 case dBOMB:
6044
3/4
✓ Branch 0 taken 1704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1087 times.
✓ Branch 3 taken 617 times.
1704 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6045 {
6046 1087 base_scr->door[i]=dBOMBED;
6047 1087 }
6048
6049 1704 break;
6050 }
6051
6052 46084 update_door(base_scr, i, base_scr->door[i]);
6053
6054
4/4
✓ Branch 0 taken 41517 times.
✓ Branch 1 taken 4567 times.
✓ Branch 2 taken 736 times.
✓ Branch 3 taken 40781 times.
46084 if(door==dSHUTTER||door==d1WAYSHUTTER)
6055 {
6056 5303 base_scr->door[i]=door;
6057 5303 }
6058 46084 }
6059 11521 }
6060
6061
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 36961 times.
37098 if (!(base_scr->flags3 & fCYCLEONINIT))
6062 36961 return;
6063
6064
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 959 times.
1096 for (int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6065 {
6066
4/4
✓ Branch 0 taken 822 times.
✓ Branch 1 taken 137 times.
✓ Branch 2 taken 377 times.
✓ Branch 3 taken 445 times.
959 if (j<0 || base_scr->layermap[j] > 0)
6067 {
6068 514 mapscr* layer_scr = get_scr_layer(screen, j + 1);
6069
3/4
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 377 times.
514 mapscr* layerscreen= (j<0 ? base_scr : layer_scr->valid ? layer_scr :
6070 &TheMaps[(base_scr->layermap[j]-1)*MAPSCRS]+base_scr->layerscreen[j]);
6071
6072
2/2
✓ Branch 0 taken 90464 times.
✓ Branch 1 taken 514 times.
90978 for(int32_t i=0; i<176; ++i)
6073 {
6074 90464 int32_t c=layerscreen->data[i];
6075
6076 // New screen flag: Cycle Combos At Screen Init
6077
5/6
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 90399 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
90464 if(combobuf[c].nextcombo != 0 && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6078 {
6079 65 int32_t r = 0;
6080
6081
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 65 times.
149 while(combobuf[c].can_cycle() && r++ < 10)
6082 {
6083 84 newcombo const& cmb = combobuf[c];
6084 84 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6085
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6086 84 layerscreen->data[i] = cid;
6087
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 69 times.
84 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6088
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6089 84 c = layerscreen->data[i];
6090 }
6091 65 }
6092 90464 }
6093 514 }
6094 959 }
6095 37098 }
6096
6097 // Set `cur_screen` to `screen` and load new screens into temporary memory.
6098 //
6099 // Called anytime a player moves to a new screen (either via warping, scrolling, continue, starting
6100 // the game, etc...)
6101 //
6102 // Note: for regions, only the initial screen load calls this function. Simply walking between
6103 // screens in the same region does not use this, because every screen in a region is loaded into
6104 // temporary memory up front.
6105 //
6106 // If scr >= 0x80, `Hero.current_screen` will be saved to `home_screen` and also be loaded into
6107 // `special_warp_return_scr`.
6108 //
6109 // If origin_screen_overlay is true, the old origin_scr combos will be copied to the new origin_scr combos
6110 // on all layers (but only where the new screen has a 0 combo).
6111 //
6112 // TODO: loadscr should set curdmap, but currently callers do that.
6113 35854 void loadscr(int32_t destdmap, int32_t screen, int32_t ldir, bool origin_screen_overlay, bool no_x80_dir)
6114 {
6115 35854 zapp_reporting_set_tag("screen", screen);
6116
2/2
✓ Branch 0 taken 8928 times.
✓ Branch 1 taken 26926 times.
35854 if (destdmap != -1)
6117 8928 zapp_reporting_set_tag("dmap", destdmap);
6118
6119 35854 int32_t orig_destdmap = destdmap;
6120
2/2
✓ Branch 0 taken 8928 times.
✓ Branch 1 taken 26926 times.
35854 if (destdmap < 0) destdmap = cur_dmap;
6121
6122
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35854 times.
35854 if (replay_is_active())
6123 {
6124
1/2
✓ Branch 0 taken 35854 times.
✗ Branch 1 not taken.
35854 if (replay_get_mode() == ReplayMode::ManualTakeover)
6125 replay_stop_manual_takeover();
6126
6127
2/2
✓ Branch 0 taken 26926 times.
✓ Branch 1 taken 8928 times.
35854 if (orig_destdmap != -1)
6128 {
6129
2/2
✓ Branch 0 taken 7857 times.
✓ Branch 1 taken 1071 times.
8928 if (strlen(DMaps[orig_destdmap].name) > 0)
6130 {
6131
1/2
✓ Branch 0 taken 7857 times.
✗ Branch 1 not taken.
7857 replay_step_comment(fmt::format("dmap={} {}", orig_destdmap, DMaps[orig_destdmap].name));
6132 7857 }
6133 else
6134 {
6135
1/2
✓ Branch 0 taken 1071 times.
✗ Branch 1 not taken.
1071 replay_step_comment(fmt::format("dmap={}", orig_destdmap));
6136 }
6137 8928 }
6138 35854 replay_step_comment_loadscr(screen);
6139
6140 // Reset the rngs and frame count so that recording steps can be modified without impacting
6141 // behavior of later screens.
6142 35854 replay_sync_rng();
6143 35854 }
6144
6145
2/2
✓ Branch 0 taken 1707536 times.
✓ Branch 1 taken 35854 times.
1743390 for (auto& state : get_screen_states())
6146 1707536 state.second.triggered_secrets = false;
6147 35854 slopes.clear();
6148 35854 Hero.clear_platform_ffc();
6149 35854 timeExitAllGenscript(GENSCR_ST_CHANGE_SCREEN);
6150 35854 clear_darkroom_bitmaps();
6151 35854 msgscr = nullptr;
6152
6153
2/2
✓ Branch 0 taken 50391860 times.
✓ Branch 1 taken 35854 times.
50427714 for (word x=0; x<animated_combos; x++)
6154 {
6155
2/2
✓ Branch 0 taken 20919990 times.
✓ Branch 1 taken 29471870 times.
50391860 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6156 {
6157 20919990 combobuf[animated_combo_table4[x][0]].aclk = 0;
6158 20919990 }
6159 50391860 }
6160 35854 reset_combo_animations2();
6161 35854 region_is_lit = false;
6162
6163 // Legacy features (combo and ffc overlays) may need the previous origin screens during loading
6164 // of the new ones.
6165 35854 bool origin_ffc_overlay = false;
6166
2/2
✓ Branch 0 taken 1137 times.
✓ Branch 1 taken 34717 times.
35854 if (origin_scr)
6167 {
6168
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 34715 times.
34717 if (!(origin_scr->flags5&fNOFFCARRYOVER))
6169 {
6170 34715 int c = origin_scr->numFFC();
6171
2/2
✓ Branch 0 taken 34571 times.
✓ Branch 1 taken 1038879 times.
1073450 for (int i = 0; i < c; i++)
6172 {
6173
2/2
✓ Branch 0 taken 1038735 times.
✓ Branch 1 taken 144 times.
1038879 if (origin_scr->ffcs[i].flags&ffc_carryover)
6174 {
6175 144 origin_ffc_overlay = true;
6176 144 break;
6177 }
6178 1038735 }
6179 34715 }
6180
6181
3/4
✓ Branch 0 taken 34717 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144 times.
✓ Branch 3 taken 34573 times.
34717 if (origin_screen_overlay || origin_ffc_overlay)
6182 {
6183
2/2
✓ Branch 0 taken 1008 times.
✓ Branch 1 taken 144 times.
1152 for (int i = 0; i <= 6; i++)
6184 {
6185 1008 mapscr* prev_scr = get_scr_layer(cur_screen, i);
6186
1/2
✓ Branch 0 taken 1008 times.
✗ Branch 1 not taken.
1008 if (prev_scr)
6187 1008 prev_origin_scrs[i] = *prev_scr;
6188 else
6189 prev_origin_scrs[i] = {};
6190 1008 }
6191 144 }
6192 34717 }
6193
6194 // When loading a new screen, all previous FFC scripts end, with one exception.
6195 // Based on origin_ffc_overlay, some ffc scripts don't get reset. This set starts with all of
6196 // them, but scripts that need their data to persist will be removed.
6197 35854 loadscr_ffc_script_ids_to_remove.clear();
6198
2/2
✓ Branch 0 taken 74698175 times.
✓ Branch 1 taken 35854 times.
74734029 for (auto& key : scriptEngineDatas | std::views::keys)
6199 {
6200
2/2
✓ Branch 0 taken 73576270 times.
✓ Branch 1 taken 1121905 times.
74698175 if (key.first == ScriptType::FFC)
6201 1121905 loadscr_ffc_script_ids_to_remove.insert(key.second);
6202 }
6203
6204 35854 load_region(destdmap, screen);
6205
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 34947 times.
35854 home_screen = screen >= 0x80 ? Hero.current_screen : cur_screen;
6206 35854 Hero.current_screen = screen;
6207
6208 35854 cpos_clear_all();
6209 35854 FFCore.destroyScriptableObjectsOfType(ScriptType::Screen);
6210 35854 FFCore.clear_combo_scripts();
6211
6212
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35690 times.
35854 if (is_in_scrolling_region())
6213 {
6214
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6215 {
6216
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6217 {
6218
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool screen_overlay = origin_screen_overlay && screen == cur_screen;
6219
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool ffc_overlay = origin_ffc_overlay && screen == cur_screen;
6220 1408 load_a_screen_and_layers_init(destdmap, screen, ldir, screen_overlay, ffc_overlay);
6221 1408 }
6222 20992 }
6223 164 }
6224 else
6225 {
6226 35690 load_a_screen_and_layers_init(destdmap, screen, ldir, origin_screen_overlay, origin_ffc_overlay);
6227 }
6228
6229 35854 prepare_current_region_handles();
6230
6231
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35690 times.
35854 if (is_in_scrolling_region())
6232 {
6233
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6234 {
6235
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6236 {
6237 1408 load_a_screen_and_layers_post(destdmap, screen, ldir);
6238 1408 }
6239 20992 }
6240 164 }
6241 else
6242 {
6243 35690 load_a_screen_and_layers_post(destdmap, screen, ldir);
6244 }
6245
6246 // If on a special screen, load the screen the player is currently on (home_screen) into special_warp_return_scr.
6247
2/2
✓ Branch 0 taken 34947 times.
✓ Branch 1 taken 907 times.
35854 if (screen >= 0x80)
6248
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 431 times.
907 loadscr_old(orig_destdmap, home_screen, no_x80_dir ? -1 : ldir, origin_screen_overlay);
6249
6250 35854 update_slope_comboposes();
6251 35854 cpos_force_update();
6252 35854 trig_trigger_groups();
6253
6254
2/2
✓ Branch 0 taken 1121631 times.
✓ Branch 1 taken 35854 times.
1157485 for (int index : loadscr_ffc_script_ids_to_remove)
6255 {
6256 // Note: ideally would use "destroySprite", but during scrolling the previous
6257 // screen's FFCs are still accessible (even though only the new screen's FFC scripts run).
6258 // The only difference is a call to "release_sprite_owned_objects". To defer FFC script
6259 // owned objects being released until the end of the scroll, here "destroyScriptableObject"
6260 // is used instead.
6261 //
6262 // So when is "release_sprite_owned_objects" called for FFCs? For scrolling screen
6263 // transitions, it's at the end of "scrollscr" via "delete_temporary_screens". Otherwise,
6264 // it is called above when "load_region" calls "clear_temporary_screens".
6265 1121631 FFCore.destroyScriptableObject(ScriptType::FFC, index);
6266 }
6267
6268 // "extended height mode" includes the top 56 pixels as part of the visible mapscr viewport,
6269 // allowing for regions to display 4 more rows of combos (as many as ALTTP does). This part of
6270 // screen is normally reserved for the passive subscreen, but in this mode mapscr combos are drawn below it.
6271 // It is up to the quest designer to make their subscreen be actually transparent.
6272 //
6273 // When not in "extended height mode" (otherwise 56 is 0):
6274 // - playing_field_offset: 56, but changes during earthquakes
6275 // - original_playing_field_offset: always 56
6276 //
6277 // These values are used to adjust where things are drawn on screen to account for the passive subscreen. Examples:
6278 // - yofs of sprites
6279 // - bitmap y offsets in draw_screen
6280 // - drawing offsets for putscr, do_layer
6281 // - drawing offsets for various calls to overtile16 (see bomb weapon explosion)
6282 // - lots more
6283 //
6284 // TODO: consider refactor of yofs, make yofs start as 0 by default and add playing_field_offset at draw time?
6285
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 35712 times.
35854 if (is_extended_height_mode())
6286 {
6287 142 playing_field_offset = 0;
6288 142 original_playing_field_offset = 0;
6289 // A few sprites exist as globals, so we must manually reset them.
6290 142 Hero.yofs = 0;
6291 142 mblock2.yofs = 0;
6292 142 }
6293 else
6294 {
6295 35712 mblock2.yofs = Hero.yofs = playing_field_offset = 56;
6296 35712 original_playing_field_offset = 56;
6297 }
6298 35854 is_any_room_dark = is_any_dark();
6299
6300 35854 game->load_portal();
6301 35854 throwGenScriptEvent(GENSCR_EVENT_CHANGE_SCREEN);
6302
3/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 35819 times.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
35854 if (Hero.lift_wpn && get_qr(qr_CARRYABLE_NO_ACROSS_SCREEN))
6303 {
6304 delete Hero.lift_wpn;
6305 Hero.lift_wpn = nullptr;
6306 }
6307
6308 35854 enemy_spawning_has_checked_been_here = false;
6309 35854 markBmap(-1, Hero.current_screen);
6310 35854 Hero.maybe_begin_advanced_maze();
6311 35854 }
6312
6313 // Don't use this directly! Use `loadscr` instead.
6314 907 void loadscr_old(int32_t destdmap, int32_t screen,int32_t ldir,bool overlay)
6315 {
6316
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int32_t destlvl = DMaps[destdmap < 0 ? cur_dmap : destdmap].level;
6317
6318 907 mapscr previous_scr = *special_warp_return_scr;
6319 907 mapscr* scr = special_warp_return_scr;
6320
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 const mapscr* source = get_canonical_scr(cur_map, screen);
6321
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 *scr = *source;
6322
6323
2/2
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 907 times.
6349 for (int i = 1; i <= 6; i++)
6324 {
6325
2/2
✓ Branch 0 taken 5059 times.
✓ Branch 1 taken 383 times.
5442 if (scr->layermap[i-1] > 0)
6326
2/4
✓ Branch 0 taken 383 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383 times.
✗ Branch 3 not taken.
383 special_warp_return_scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6327 else
6328
2/4
✓ Branch 0 taken 5059 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5059 times.
✗ Branch 3 not taken.
5059 special_warp_return_scrs[i] = {};
6329 5442 }
6330
6331 907 scr->valid |= mVALID; //layer 0 is always valid
6332
6333
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 907 times.
907 if ( source->script > 0 )
6334 {
6335 scr->script = source->script;
6336 for ( int32_t q = 0; q < 8; q++ )
6337 {
6338 scr->screeninitd[q] = source->screeninitd[q];
6339 }
6340 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6341 }
6342 else
6343 {
6344 907 scr->script = 0;
6345 }
6346
6347
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 if(overlay)
6348 {
6349 for(int32_t c=0; c< 176; ++c)
6350 {
6351 if(scr->data[c]==0)
6352 {
6353 scr->data[c]=previous_scr.data[c];
6354 scr->sflag[c]=previous_scr.sflag[c];
6355 scr->cset[c]=previous_scr.cset[c];
6356 }
6357 }
6358
6359 for(int32_t i=0; i<6; i++)
6360 {
6361 if(previous_scr.layermap[i]>0 && scr->layermap[i]>0)
6362 {
6363 int32_t lm = (scr->layermap[i]-1)*MAPSCRS+scr->layerscreen[i];
6364 int32_t fm = (previous_scr.layermap[i]-1)*MAPSCRS+previous_scr.layerscreen[i];
6365
6366 for(int32_t c=0; c< 176; ++c)
6367 {
6368 if(TheMaps[lm].data[c]==0)
6369 {
6370 TheMaps[lm].data[c] = TheMaps[fm].data[c];
6371 TheMaps[lm].sflag[c] = TheMaps[fm].sflag[c];
6372 TheMaps[lm].cset[c] = TheMaps[fm].cset[c];
6373 }
6374 }
6375 }
6376 }
6377 }
6378
6379
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
29900 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6380
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int c = scr->numFFC();
6381
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 28993 times.
29900 for (word i = 0; i < c; i++)
6382 {
6383 28993 scr->ffcs[i].screen_spawned = screen;
6384
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].x += offx;
6385
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].y += offy;
6386 28993 }
6387
6388 907 int mi = mapind(cur_map, screen);
6389
6390 // Apply perm secrets, if applicable.
6391
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if(canPermSecret(destdmap,screen))
6392 {
6393
3/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 332 times.
536 if(game->maps[mi]&mSECRET) // if special stuff done before
6394 {
6395
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 reveal_hidden_stairs(scr, screen, false);
6396
6397
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
6398
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 get_screen_state(special_warp_return_scr->screen).triggered_secrets = true;
6399 204 bool do_replay_comment = true;
6400 204 bool from_active_screen = false;
6401
2/4
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✗ Branch 3 not taken.
204 trigger_secrets_for_screen_internal(create_screen_handles(special_warp_return_scr), from_active_screen, false, -1, do_replay_comment);
6402 204 }
6403
2/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✗ Branch 3 not taken.
536 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6404 {
6405 for (int layer = 0; layer <= 6; layer++)
6406 {
6407 mapscr* tscr = &special_warp_return_scrs[layer];
6408 for (int pos = 0; pos < 176; pos++)
6409 {
6410 newcombo const* cmb = &combobuf[tscr->data[pos]];
6411 if(cmb->type == cLIGHTTARGET)
6412 {
6413 if(!(cmb->usrflags&cflag1)) //Unlit version
6414 {
6415 tscr->data[pos] += 1;
6416 }
6417 }
6418 }
6419 }
6420 }
6421 536 }
6422
6423 screen_handles_t screen_handles;
6424
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 6349 times.
7256 for (int i = 0; i <= 6; i++)
6425
3/4
✓ Branch 0 taken 6349 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1284 times.
✓ Branch 3 taken 5065 times.
6349 screen_handles[i] = {scr, special_warp_return_scrs[i].is_valid() ? &special_warp_return_scrs[i] : nullptr, screen, i};
6426
6427
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 907 times.
✗ Branch 3 not taken.
907 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6428
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 toggle_gswitches_load(screen_handles);
6429
6430
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 902 times.
907 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6431 {
6432
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 remove_lockblocks(screen_handles);
6433 5 }
6434
6435
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 906 times.
907 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6436 {
6437
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6438 1 }
6439
6440
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mCHEST) // if special stuff done before
6441 {
6442 remove_chests(screen_handles);
6443 }
6444
6445
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6446 {
6447 remove_lockedchests(screen_handles);
6448 }
6449
6450
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6451 {
6452 remove_bosschests(screen_handles);
6453 }
6454
6455
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xdoors(screen_handles, true);
6456
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xstatecombos(screen_handles, true);
6457
6458 // check doors
6459
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if (isdungeon(destdmap, screen))
6460 {
6461
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 371 times.
1855 for(int32_t i=0; i<4; i++)
6462 {
6463 1484 int32_t door=scr->door[i];
6464
6465
4/5
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 89 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1295 times.
1484 switch(door)
6466 {
6467 case d1WAYSHUTTER:
6468 case dSHUTTER:
6469 if ((ldir^1)==i && screen == home_screen)
6470 {
6471 scr->door[i]=dOPENSHUTTER;
6472 }
6473
6474 get_screen_state(screen).open_doors = -4;
6475 105 break;
6476
6477 case dLOCKED:
6478
3/4
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 80 times.
91 if(game->maps[mi]&(mDOOR_UP<<i))
6479 {
6480 80 scr->door[i]=dUNLOCKED;
6481 80 }
6482
6483 91 break;
6484
6485 case dBOSS:
6486
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 5 times.
9 if(game->maps[mi]&(mDOOR_UP<<i))
6487 {
6488 5 scr->door[i]=dOPENBOSS;
6489 5 }
6490
6491 9 break;
6492
6493 case dBOMB:
6494
3/4
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 51 times.
89 if(game->maps[mi]&(mDOOR_UP<<i))
6495 {
6496 51 scr->door[i]=dBOMBED;
6497 51 }
6498
6499 89 break;
6500 }
6501
6502
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 105 times.
1589 update_door(scr, i, scr->door[i]);
6503
6504
4/4
✓ Branch 0 taken 1390 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1379 times.
1484 if(door==dSHUTTER||door==d1WAYSHUTTER)
6505 {
6506 105 scr->door[i]=door;
6507 105 }
6508 1484 }
6509 371 }
6510
6511
2/2
✓ Branch 0 taken 6139 times.
✓ Branch 1 taken 1117 times.
7256 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6512 {
6513
4/4
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 697 times.
✓ Branch 2 taken 593 times.
✓ Branch 3 taken 4849 times.
6139 if (j<0 || scr->layermap[j] > 0)
6514 {
6515
4/4
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 907 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 1 times.
1290 mapscr *layerscreen= (j<0 ? scr : special_warp_return_scrs[j+1].valid ? &special_warp_return_scrs[j+1] :
6516 1 &TheMaps[(scr->layermap[j]-1)*MAPSCRS]+scr->layerscreen[j]);
6517
6518
2/2
✓ Branch 0 taken 226830 times.
✓ Branch 1 taken 1500 times.
228330 for(int32_t i=0; i<176; ++i)
6519 {
6520 226830 int32_t c=layerscreen->data[i];
6521
6522 // New screen flag: Cycle Combos At Screen Init
6523
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 226824 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 210 times.
✓ Branch 7 taken 210 times.
226830 if(combobuf[c].nextcombo != 0 && (scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6524 {
6525 210 int32_t r = 0;
6526
6527
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 210 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
210 while(combobuf[c].can_cycle() && r++ < 10)
6528 {
6529 newcombo const& cmb = combobuf[c];
6530 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6531 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6532 layerscreen->data[i] = cid;
6533 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6534 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6535 c = layerscreen->data[i];
6536 }
6537 }
6538 227040 }
6539 1500 }
6540 6349 }
6541 1537 }
6542
6543 // Load screen (and layers). Unlike loadscr, this doesn't load to the global temporary_screens, but
6544 // instead returns an array of mapscr.
6545 // Used to draw/save the map.
6546 45680 std::array<mapscr, 7> loadscr2(int32_t screen)
6547 {
6548 45680 std::array<mapscr, 7> scrs;
6549 45680 mapscr* scr = &scrs[0];
6550
6551
2/2
✓ Branch 0 taken 64716181 times.
✓ Branch 1 taken 45680 times.
64761861 for(word x=0; x<animated_combos; x++)
6552 {
6553
2/2
✓ Branch 0 taken 31963685 times.
✓ Branch 1 taken 32752496 times.
64716181 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6554 {
6555 32752496 combobuf[animated_combo_table4[x][0]].aclk=0;
6556 32752496 }
6557 64716181 }
6558
6559
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 const mapscr* source = get_canonical_scr(cur_map, screen);
6560
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if (!source->is_valid())
6561 {
6562 scrs[0].valid = 0;
6563 return scrs;
6564 }
6565
6566
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 *scr = *get_canonical_scr(cur_map, screen);
6567
2/2
✓ Branch 0 taken 274080 times.
✓ Branch 1 taken 45680 times.
319760 for (int i = 1; i <= 6; i++)
6568 {
6569
2/2
✓ Branch 0 taken 209266 times.
✓ Branch 1 taken 64814 times.
274080 if (scr->layermap[i-1] > 0)
6570
2/4
✓ Branch 0 taken 64814 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64814 times.
✗ Branch 3 not taken.
64814 scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6571 else
6572
2/4
✓ Branch 0 taken 209266 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 209266 times.
✗ Branch 3 not taken.
209266 scrs[i] = {};
6573 274080 }
6574
6575 screen_handles_t screen_handles;
6576
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 319760 times.
365440 for (int i = 0; i < 7; i++)
6577
3/4
✓ Branch 0 taken 319760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103061 times.
✓ Branch 3 taken 216699 times.
319760 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
6578
6579 45680 int mi = mapind(cur_map, screen);
6580
6581
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45626 times.
✓ Branch 3 taken 54 times.
45680 if(canPermSecret(-1,screen))
6582 {
6583
3/4
✓ Branch 0 taken 45626 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5730 times.
✓ Branch 3 taken 39896 times.
45626 if(game->maps[mi]&mSECRET) // if special stuff done before
6584 {
6585
1/2
✓ Branch 0 taken 5730 times.
✗ Branch 1 not taken.
5730 reveal_hidden_stairs(scr, screen, false);
6586 5730 bool from_active_screen = false;
6587 5730 bool do_replay_comment = true;
6588
1/2
✓ Branch 0 taken 5730 times.
✗ Branch 1 not taken.
5730 trigger_secrets_for_screen_internal(screen_handles, from_active_screen, false, -1, do_replay_comment);
6589 5730 }
6590
3/4
✓ Branch 0 taken 45626 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45609 times.
✓ Branch 3 taken 17 times.
45626 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6591 {
6592
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 17 times.
136 for (int layer = 0; layer <= 6; layer++)
6593 {
6594 119 mapscr* tscr = &scrs[layer];
6595
2/2
✓ Branch 0 taken 20944 times.
✓ Branch 1 taken 119 times.
21063 for (int pos = 0; pos < 176; pos++)
6596 {
6597 20944 newcombo const* cmb = &combobuf[tscr->data[pos]];
6598
2/2
✓ Branch 0 taken 20927 times.
✓ Branch 1 taken 17 times.
20944 if(cmb->type == cLIGHTTARGET)
6599 {
6600
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!(cmb->usrflags&cflag1)) //Unlit version
6601 {
6602 17 tscr->data[pos] += 1;
6603 17 }
6604 17 }
6605 20944 }
6606 119 }
6607 17 }
6608 45626 }
6609
6610
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 233 times.
✓ Branch 3 taken 45447 times.
45680 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6611 {
6612
1/2
✓ Branch 0 taken 233 times.
✗ Branch 1 not taken.
233 remove_lockblocks(screen_handles);
6613 233 }
6614
6615
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 45679 times.
45680 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6616 {
6617
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6618 1 }
6619
6620
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
✓ Branch 3 taken 45579 times.
45680 if(game->maps[mi]&mCHEST) // if special stuff done before
6621 {
6622
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 remove_chests(screen_handles);
6623 101 }
6624
6625
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 45656 times.
45680 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6626 {
6627
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 remove_lockedchests(screen_handles);
6628 24 }
6629
6630
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45680 times.
45680 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6631 {
6632 remove_bosschests(screen_handles);
6633 }
6634
6635
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 clear_xdoors(screen_handles);
6636
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 clear_xstatecombos(screen_handles);
6637
6638 // check doors
6639
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45626 times.
✓ Branch 3 taken 54 times.
45680 if (isdungeon(screen))
6640 {
6641
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 54 times.
270 for(int32_t i=0; i<4; i++)
6642 {
6643 216 int32_t door=scr->door[i];
6644 216 bool putit=true;
6645
6646
4/5
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 61 times.
✓ Branch 4 taken 139 times.
216 switch(door)
6647 {
6648 case d1WAYSHUTTER:
6649 case dSHUTTER:
6650 61 break;
6651
6652 case dLOCKED:
6653
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(game->maps[mi]&(mDOOR_UP<<i))
6654 {
6655 12 scr->door[i]=dUNLOCKED;
6656 12 }
6657
6658 12 break;
6659
6660 case dBOSS:
6661
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(game->maps[mi]&(mDOOR_UP<<i))
6662 {
6663 scr->door[i]=dOPENBOSS;
6664 }
6665
6666 4 break;
6667
6668 case dBOMB:
6669 if(game->maps[mi]&(mDOOR_UP<<i))
6670 {
6671 scr->door[i]=dBOMBED;
6672 }
6673
6674 break;
6675 }
6676
6677
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(putit)
6678 {
6679
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 putdoor(scr, scrollbuf, i, scr->door[i], false);
6680 216 }
6681
6682
3/4
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
216 if(door==dSHUTTER||door==d1WAYSHUTTER)
6683 {
6684 61 scr->door[i]=door;
6685 61 }
6686 216 }
6687 54 }
6688
6689
2/2
✓ Branch 0 taken 319760 times.
✓ Branch 1 taken 45680 times.
365440 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6690 {
6691
4/4
✓ Branch 0 taken 274080 times.
✓ Branch 1 taken 45680 times.
✓ Branch 2 taken 64814 times.
✓ Branch 3 taken 209266 times.
319760 if (j < 0 || scr->layermap[j] > 0)
6692 {
6693
2/2
✓ Branch 0 taken 64814 times.
✓ Branch 1 taken 45680 times.
110494 mapscr *layerscreen= (j<0 ? scr
6694 64814 : &(TheMaps[(scr->layermap[j]-1)*MAPSCRS+scr->layerscreen[j]]));
6695
6696
2/2
✓ Branch 0 taken 19446944 times.
✓ Branch 1 taken 110494 times.
19557438 for(int32_t i=0; i<176; ++i)
6697 {
6698 19446944 int32_t c=layerscreen->data[i];
6699
6700 // New screen flag: Cycle Combos At Screen Init
6701
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 19446944 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
19446944 if((scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6702 {
6703 int32_t r = 0;
6704
6705 while(combobuf[c].can_cycle() && r++ < 10)
6706 {
6707 newcombo const& cmb = combobuf[c];
6708 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6709 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6710 layerscreen->data[i] = cid;
6711 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6712 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6713 c = layerscreen->data[i];
6714 }
6715 }
6716 19446944 }
6717 110494 }
6718 319760 }
6719
6720 45680 return scrs;
6721
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 }
6722
6723 19016051 void putscr(mapscr* scr, BITMAP* dest, int32_t x, int32_t y)
6724 {
6725 // This is a bogus value while screenscrolling == true, but that's ok
6726 // because it is only used to calculate the rpos, and during screenscrolling
6727 // only the modulus to get pos (draw_cmb_pos does RPOS_TO_POS) is needed, which
6728 // is always the same no matter the value of scr.
6729 19016051 int screen = get_screen_for_world_xy(x, y);
6730
6731 19016051 x -= viewport.x;
6732 19016051 y -= viewport.y;
6733
6734
3/6
✓ Branch 0 taken 19016051 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19016051 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19016051 times.
19016051 if (!scr->is_valid()||!show_layers[0]||scr->hidelayers & 1)
6735 {
6736 rectfill(dest,x,y,x+255,y+175,0);
6737 return;
6738 }
6739
6740 37903193 bool over = XOR(scr->flags7&fLAYER2BG,DMaps[cur_dmap].flags&dmfLAYER2BG)
6741
2/2
✓ Branch 0 taken 128909 times.
✓ Branch 1 taken 18887142 times.
19016051 || XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG);
6742
6743 int start_x, end_x, start_y, end_y;
6744 19016051 get_bounds_for_draw_cmb_calls(dest, x, y, start_x, end_x, start_y, end_y);
6745
2/2
✓ Branch 0 taken 19016051 times.
✓ Branch 1 taken 202549048 times.
221565099 for (int cy = start_y; cy < end_y; cy++)
6746 {
6747
2/2
✓ Branch 0 taken 3075834962 times.
✓ Branch 1 taken 202549048 times.
3278384010 for (int cx = start_x; cx < end_x; cx++)
6748 {
6749 3075834962 int i = cx + cy*16;
6750
2/2
✓ Branch 0 taken 357850966 times.
✓ Branch 1 taken 2717983996 times.
3075834962 auto rpos = screenscrolling ? rpos_t::None : POS_TO_RPOS(i, screen);
6751 3075834962 draw_cmb_pos(dest, x + cx*16, y + cy*16, rpos, scr->data[i], scr->cset[i], 0, over, false);
6752 3075834962 }
6753 202549048 }
6754 19016051 }
6755
6756 15539765 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y)
6757 {
6758
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
15539765 if (!show_layers[0])
6759 {
6760 return;
6761 }
6762
6763 15539765 x -= viewport.x;
6764 15539765 y -= viewport.y;
6765
6766
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
6767 15676083 mapscr* scr = screen_handles[0].base_scr;
6768
1/2
✓ Branch 0 taken 15676083 times.
✗ Branch 1 not taken.
15676083 if (!scr->is_valid())
6769 return;
6770
6771
2/2
✓ Branch 0 taken 123411 times.
✓ Branch 1 taken 15552672 times.
15676083 if(scr->door[0]==dBOMBED)
6772 {
6773 123411 over_door(scr, dest, 39, up, offx+x, offy+y);
6774 123411 }
6775
6776
2/2
✓ Branch 0 taken 143109 times.
✓ Branch 1 taken 15532974 times.
15676083 if(scr->door[1]==dBOMBED)
6777 {
6778 143109 over_door(scr, dest, 135, down, offx+x, offy+y);
6779 143109 }
6780
6781
2/2
✓ Branch 0 taken 155862 times.
✓ Branch 1 taken 15520221 times.
15676083 if(scr->door[2]==dBOMBED)
6782 {
6783 155862 over_door(scr, dest, 66, left, offx+x, offy+y);
6784 155862 }
6785
6786
2/2
✓ Branch 0 taken 132289 times.
✓ Branch 1 taken 15543794 times.
15676083 if(scr->door[3]==dBOMBED)
6787 {
6788 132289 over_door(scr, dest, 77, right, offx+x, offy+y);
6789 132289 }
6790 15676083 });
6791 15539765 }
6792
6793 3339968 void putscrdoors(mapscr* scr, BITMAP *dest, int32_t x, int32_t y)
6794 {
6795
2/4
✓ Branch 0 taken 3339968 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3339968 times.
✗ Branch 3 not taken.
3339968 if (!scr->is_valid() || !show_layers[0])
6796 return;
6797
6798 3339968 x -= viewport.x;
6799 3339968 y -= viewport.y;
6800
6801
2/2
✓ Branch 0 taken 37656 times.
✓ Branch 1 taken 3302312 times.
3339968 if(scr->door[0]==dBOMBED)
6802 {
6803 37656 over_door(scr,dest,39,up,x,y);
6804 37656 }
6805
6806
2/2
✓ Branch 0 taken 36495 times.
✓ Branch 1 taken 3303473 times.
3339968 if(scr->door[1]==dBOMBED)
6807 {
6808 36495 over_door(scr,dest,135,down,x,y);
6809 36495 }
6810
6811
2/2
✓ Branch 0 taken 40440 times.
✓ Branch 1 taken 3299528 times.
3339968 if(scr->door[2]==dBOMBED)
6812 {
6813 40440 over_door(scr,dest,66,left,x,y);
6814 40440 }
6815
6816
2/2
✓ Branch 0 taken 37063 times.
✓ Branch 1 taken 3302905 times.
3339968 if(scr->door[3]==dBOMBED)
6817 {
6818 37063 over_door(scr,dest,77,right,x,y);
6819 37063 }
6820 3339968 }
6821 233951335 static inline bool standing_on_z(newcombo const& cmb, zfix const& standing_z_state)
6822 {
6823 233951335 zfix cmb_z, cmb_z_step;
6824
4/4
✓ Branch 0 taken 92789 times.
✓ Branch 1 taken 233858546 times.
✓ Branch 2 taken 88819 times.
✓ Branch 3 taken 3970 times.
233951335 if(cmb.type == cCSWITCHBLOCK && (cmb.usrflags & cflag9))
6825 {
6826 3970 cmb_z = zslongToFix(cmb.attributes[2]);
6827
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3970 times.
3970 cmb_z_step = zslongToFix(zc_max(0,cmb.attributes[3]));
6828 3970 }
6829
2/2
✓ Branch 0 taken 1983 times.
✓ Branch 1 taken 233945382 times.
233947365 else if(cmb.genflags & cflag3)
6830 {
6831 1983 cmb_z = cmb.z_height;
6832
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1983 times.
1983 cmb_z_step = zc_max(0_zf,cmb.z_step_height);
6833 1983 }
6834 233945382 else return false;
6835
6836
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5953 times.
✓ Branch 2 taken 4804 times.
✓ Branch 3 taken 1149 times.
5953 return (standing_z_state < 0 || (cmb_z>0 && (cmb_z - cmb_z_step) <= standing_z_state));
6837 233951335 }
6838 56117558 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt)
6839 {
6840 56117558 return _walkflag(zx,zy,cnt,0_zf);
6841 }
6842
6843 132920561 bool _walkflag_new(const mapscr* s0, const mapscr* s1, const mapscr* s2, zfix_round zx, zfix_round zy, zfix const& standing_z_state, bool is_temp_screens)
6844 {
6845 132920561 int x = zx.getRound(), y = zy.getRound();
6846 132920561 int pos = COMBOPOS(x % 256, y % 176);
6847 132920561 const newcombo& c = combobuf[s0->data[pos]];
6848 132920561 const newcombo& c1 = combobuf[s1->data[pos]];
6849 132920561 const newcombo& c2 = combobuf[s2->data[pos]];
6850
4/4
✓ Branch 0 taken 130925120 times.
✓ Branch 1 taken 1995441 times.
✓ Branch 2 taken 130915660 times.
✓ Branch 3 taken 9460 times.
266043410 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
6851
4/4
✓ Branch 0 taken 101153 times.
✓ Branch 1 taken 131016795 times.
✓ Branch 2 taken 2101809 times.
✓ Branch 3 taken 4245 times.
132920561 (iswater_type(c2.type))) && DRIEDLAKE);
6852 133122849 int32_t b=1;
6853
2/2
✓ Branch 0 taken 65628846 times.
✓ Branch 1 taken 67494003 times.
133122849 if(x&8) b<<=2;
6854
2/2
✓ Branch 0 taken 62187457 times.
✓ Branch 1 taken 70935392 times.
133122849 if(y&8) b<<=1;
6855
6856 133122849 int32_t cwalkflag = c.walk;
6857
4/4
✓ Branch 0 taken 133021705 times.
✓ Branch 1 taken 101144 times.
✓ Branch 2 taken 133021541 times.
✓ Branch 3 taken 164 times.
133122849 if(is_temp_screens && standing_on_z(c,standing_z_state)) cwalkflag &= (c.walk>>4)^0xF;
6858
8/10
✓ Branch 0 taken 50572 times.
✓ Branch 1 taken 133072113 times.
✓ Branch 2 taken 2096585 times.
✓ Branch 3 taken 2046013 times.
✓ Branch 4 taken 2096585 times.
✓ Branch 5 taken 133021541 times.
✓ Branch 6 taken 2096585 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2096585 times.
✗ Branch 9 not taken.
133122685 else if ((c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) || (iswater_type(c.type) && ((c.walk>>4)&b) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
6859
2/2
✓ Branch 0 taken 63198695 times.
✓ Branch 1 taken 69823010 times.
133021705 if (s1 != s0)
6860 {
6861
3/4
✓ Branch 0 taken 69823010 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69822392 times.
✓ Branch 3 taken 618 times.
69823010 if(is_temp_screens && standing_on_z(c1,standing_z_state)) cwalkflag &= (c1.walk>>4)^0xF;
6862
4/10
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 69810663 times.
✓ Branch 2 taken 11729 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11729 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
69822392 else if ((iswater_type(c1.type) && ((c1.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_1) && !((c1.usrflags&cflag3) || (c1.usrflags&cflag4)))) cwalkflag &= c1.walk;
6863
2/2
✓ Branch 0 taken 62906 times.
✓ Branch 1 taken 69759486 times.
69822392 else if (c1.type == cBRIDGE)
6864 {
6865
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62906 times.
62906 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
6866 {
6867 62906 int efflag = (c1.walk & 0xF0)>>4;
6868 62906 int newsolid = (c1.walk & 0xF);
6869 62906 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
6870 62906 }
6871 else cwalkflag &= c1.walk;
6872 62906 }
6873
3/8
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 69747757 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11729 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
69759486 else if ((iswater_type(c1.type) && get_qr(qr_WATER_ON_LAYER_1) && ((c1.usrflags&cflag3) || (c1.usrflags&cflag4)) && ((c1.walk>>4)&b))) cwalkflag = 0;
6874 69759486 else cwalkflag |= c1.walk;
6875 69823010 }
6876
2/2
✓ Branch 0 taken 101915085 times.
✓ Branch 1 taken 31106620 times.
133021705 if (s2 != s0)
6877 {
6878
2/4
✓ Branch 0 taken 31106620 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 31106620 times.
✗ Branch 3 not taken.
31106620 if(is_temp_screens && standing_on_z(c2,standing_z_state)) cwalkflag &= (c2.walk>>4)^0xF;
6879
4/10
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 31104466 times.
✓ Branch 2 taken 2154 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2154 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
31106620 else if ((iswater_type(c2.type) && ((c2.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_2) && !((c2.usrflags&cflag3) || (c2.usrflags&cflag4)))) cwalkflag &= c2.walk;
6880
2/2
✓ Branch 0 taken 4447 times.
✓ Branch 1 taken 31102173 times.
31106620 else if (c2.type == cBRIDGE)
6881 {
6882
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4447 times.
4447 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
6883 {
6884 4447 int efflag = (c2.walk & 0xF0)>>4;
6885 4447 int newsolid = (c2.walk & 0xF);
6886 4447 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
6887 4447 }
6888 else cwalkflag &= c2.walk;
6889 4447 }
6890
3/8
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 31100019 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2154 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
31102173 else if ((iswater_type(c2.type) && get_qr(qr_WATER_ON_LAYER_2) && ((c2.usrflags&cflag3) || (c2.usrflags&cflag4))) && ((c2.walk>>4)&b)) cwalkflag = 0;
6891 31102173 else cwalkflag |= c2.walk;
6892 31106620 }
6893
6894
4/4
✓ Branch 0 taken 29568194 times.
✓ Branch 1 taken 103453511 times.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 29567246 times.
133021705 if((cwalkflag&b) && !dried)
6895 29567246 return true;
6896
6897
3/4
✓ Branch 0 taken 103454459 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103438048 times.
✓ Branch 3 taken 16411 times.
103454459 if (is_temp_screens && collide_object(zx, zy, 0.0001_zf, 0.0001_zf)) return true;
6898
6899 103438048 return false;
6900 133021705 }
6901
6902 // Returns true if the combo at viewport position x,y is solid. Looks at a combo's quadrant walkablity flags.
6903 133021705 static bool _walkflag_new(zfix_round zx, zfix_round zy, zfix const& standing_z_state)
6904 {
6905 133021705 int x = zx.getRound(), y = zy.getRound();
6906 133021705 mapscr* s0 = get_scr_for_world_xy_layer(x, y, 0);
6907 133021705 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
6908 133021705 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
6909
2/2
✓ Branch 0 taken 63198695 times.
✓ Branch 1 taken 69823010 times.
133021705 if (!s1->valid) s1 = s0;
6910
2/2
✓ Branch 0 taken 101915085 times.
✓ Branch 1 taken 31106620 times.
133021705 if (!s2->valid) s2 = s0;
6911 133021705 return _walkflag_new(s0, s1, s2, zx, zy, standing_z_state, true);
6912 }
6913
6914 128587954 bool _walkflag(zfix_round x,zfix_round y,int32_t cnt,zfix const& standing_z_state)
6915 {
6916 128587954 int max_x = world_w;
6917 128587954 int max_y = world_h;
6918
2/2
✓ Branch 0 taken 68545217 times.
✓ Branch 1 taken 60042737 times.
128587954 if (!get_qr(qr_LTTPWALK))
6919 {
6920 60042737 max_x -= 7;
6921 60042737 max_y -= 7;
6922 60042737 }
6923
4/4
✓ Branch 0 taken 128317122 times.
✓ Branch 1 taken 270832 times.
✓ Branch 2 taken 83268 times.
✓ Branch 3 taken 128233854 times.
128587954 if (x < 0 || y < 0) return false;
6924
2/2
✓ Branch 0 taken 322356 times.
✓ Branch 1 taken 127911498 times.
128233854 if (x >= max_x) return false;
6925
3/4
✓ Branch 0 taken 539663 times.
✓ Branch 1 taken 127371835 times.
✓ Branch 2 taken 539663 times.
✗ Branch 3 not taken.
127911498 if (x >= max_x - 8 && cnt == 2) return false;
6926
2/2
✓ Branch 0 taken 127362274 times.
✓ Branch 1 taken 549224 times.
127911498 if (y >= max_y) return false;
6927
6928
4/4
✓ Branch 0 taken 29465504 times.
✓ Branch 1 taken 97896770 times.
✓ Branch 2 taken 92237339 times.
✓ Branch 3 taken 5659431 times.
127362274 return _walkflag_new(x, y, standing_z_state) || (cnt != 1 && _walkflag_new(x + 8, y, standing_z_state));
6929 128587954 }
6930
6931 99145230 static bool effectflag(int32_t x, int32_t y, int32_t layer)
6932 {
6933 99145230 mapscr* s0 = get_scr_for_world_xy(x, y);
6934 99145230 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
6935 99145230 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
6936
2/2
✓ Branch 0 taken 51697279 times.
✓ Branch 1 taken 47447951 times.
99145230 if (!s1->valid) s1 = s0;
6937
2/2
✓ Branch 0 taken 18749698 times.
✓ Branch 1 taken 80395532 times.
99145230 if (!s2->valid) s2 = s0;
6938
6939 99145230 int pos = COMBOPOS(x % 256, y % 176);
6940 99145230 const newcombo& c = combobuf[s0->data[pos]];
6941 99145230 const newcombo& c1 = combobuf[s1->data[pos]];
6942 99145230 const newcombo& c2 = combobuf[s2->data[pos]];
6943
4/4
✓ Branch 0 taken 98220191 times.
✓ Branch 1 taken 925039 times.
✓ Branch 2 taken 98218911 times.
✓ Branch 3 taken 1280 times.
198290460 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
6944
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 98218911 times.
✓ Branch 2 taken 924635 times.
✓ Branch 3 taken 1684 times.
99145230 (iswater_type(c2.type))) && DRIEDLAKE);
6945 99145230 int32_t b=1;
6946
2/2
✓ Branch 0 taken 50171272 times.
✓ Branch 1 taken 48973958 times.
99145230 if(x&8) b<<=2;
6947
2/2
✓ Branch 0 taken 41919837 times.
✓ Branch 1 taken 57225393 times.
99145230 if(y&8) b<<=1;
6948
6949 99145230 int32_t cwalkflag = (c.walk>>4);
6950
2/2
✓ Branch 0 taken 76351629 times.
✓ Branch 1 taken 22793601 times.
99145230 if (layer == 0) cwalkflag = (c1.walk>>4);
6951
2/2
✓ Branch 0 taken 76352827 times.
✓ Branch 1 taken 22792403 times.
99145230 if (layer == 1) cwalkflag = (c2.walk>>4);
6952 //if (c.type == cBRIDGE || (iswater_type(c.type) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
6953
4/4
✓ Branch 0 taken 51697279 times.
✓ Branch 1 taken 47447951 times.
✓ Branch 2 taken 22531992 times.
✓ Branch 3 taken 29165287 times.
99145230 if (s1 != s0 && layer < 0)
6954 {
6955
2/2
✓ Branch 0 taken 22518486 times.
✓ Branch 1 taken 13506 times.
22531992 if (c1.type == cBRIDGE) cwalkflag &= (~(c1.walk>>4));
6956 22531992 }
6957
4/4
✓ Branch 0 taken 18749698 times.
✓ Branch 1 taken 80395532 times.
✓ Branch 2 taken 13831481 times.
✓ Branch 3 taken 4918217 times.
99145230 if (s2 != s0 && layer < 1)
6958 {
6959
2/2
✓ Branch 0 taken 13825621 times.
✓ Branch 1 taken 5860 times.
13831481 if (c2.type == cBRIDGE) cwalkflag &= (~(c2.walk>>4));
6960 13831481 }
6961
6962
2/2
✓ Branch 0 taken 98985906 times.
✓ Branch 1 taken 159324 times.
99145230 return (cwalkflag&b) ? !dried : false;
6963 }
6964
6965 99518554 bool _effectflag(int32_t x,int32_t y,int32_t cnt, int32_t layer, bool notLink)
6966 {
6967 DCHECK(cnt == 0 || cnt == 1);
6968 99518554 int max_x = world_w;
6969 99518554 int max_y = world_h;
6970
3/4
✓ Branch 0 taken 45833723 times.
✓ Branch 1 taken 53684831 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45833723 times.
99518554 if (!get_qr(qr_LTTPWALK) && !notLink)
6971 {
6972 45833723 max_x -= 7;
6973 45833723 max_y -= 7;
6974 45833723 }
6975
4/4
✓ Branch 0 taken 99517802 times.
✓ Branch 1 taken 752 times.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 99517598 times.
99518554 if (x < 0 || y < 0) return false;
6976
2/2
✓ Branch 0 taken 816 times.
✓ Branch 1 taken 99516782 times.
99517598 if (x >= max_x) return false;
6977
3/4
✓ Branch 0 taken 520196 times.
✓ Branch 1 taken 98996586 times.
✓ Branch 2 taken 520196 times.
✗ Branch 3 not taken.
99516782 if (x >= max_x - 8 && cnt == 2) return false;
6978
2/2
✓ Branch 0 taken 371552 times.
✓ Branch 1 taken 99145230 times.
99516782 if (y >= max_y) return false;
6979
6980
3/4
✓ Branch 0 taken 98985116 times.
✓ Branch 1 taken 160114 times.
✓ Branch 2 taken 160114 times.
✗ Branch 3 not taken.
99145230 return effectflag(x, y, layer) || (cnt == 2 && effectflag(x + 8, y, layer));
6981 99518554 }
6982
6983 // used by mapdata->isSolid(x,y) in ZScript
6984 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
6985 {
6986 int x = zx.getRound(), y = zy.getRound();
6987 {
6988 int max_x = 256;
6989 int max_y = 176;
6990 if (!get_qr(qr_LTTPWALK))
6991 {
6992 max_x -= 7;
6993 max_y -= 7;
6994 }
6995 if (x < 0 || y < 0) return false;
6996 if (x >= max_x) return false;
6997 if (x >= max_x - 8 && cnt == 2) return false;
6998 if (y >= max_y) return false;
6999 }
7000
7001 const mapscr *s1, *s2;
7002
7003 if ( m->layermap[0] > 0 )
7004 {
7005 s1 = get_canonical_scr(m->layermap[0], m->layerscreen[0]);
7006 }
7007 else s1 = m;
7008
7009 if ( m->layermap[1] > 0 )
7010 {
7011 s2 = get_canonical_scr(m->layermap[1], m->layerscreen[1]);
7012 }
7013 else s2 = m;
7014
7015 zfix unused;
7016 return _walkflag_new(m, s1, s2, x, y, unused, false) || (cnt != 1 && _walkflag_new(m, s1, s2, x + 8, y, unused, false));
7017 }
7018
7019 bool _walkflag_layer(zfix_round x, zfix_round y, int32_t layer, int32_t cnt)
7020 {
7021 DCHECK_LAYER_NEG1_INDEX(layer);
7022 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7023 if (!m->is_valid()) return false;
7024 return _walkflag_layer(x, y, cnt, m);
7025 }
7026
7027 static bool _walkflag_layer_new(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m, int max_x, int max_y)
7028 {
7029 int x = zx.getRound(), y = zy.getRound();
7030
7031 if (!get_qr(qr_LTTPWALK))
7032 {
7033 max_x -= 7;
7034 max_y -= 7;
7035 }
7036 if (x < 0 || y < 0) return false;
7037 if (x >= max_x) return false;
7038 if (x >= max_x - 8 && cnt == 2) return false;
7039 if (y >= max_y) return false;
7040
7041 if(!m) return true;
7042
7043 int pos = COMBOPOS(x%256, y%176);
7044 const newcombo* c = &combobuf[m->data[pos]];
7045 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7046 int32_t b=1;
7047
7048 if(x&8) b<<=2;
7049
7050 if(y&8) b<<=1;
7051
7052 if((c->walk&b) && !dried)
7053 return true;
7054
7055 if(cnt==1) return false;
7056
7057 ++pos;
7058
7059 if(!(x&8))
7060 b<<=2;
7061 else
7062 {
7063 c = &combobuf[m->data[pos]];
7064 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7065 b=1;
7066
7067 if(y&8) b<<=1;
7068 }
7069
7070 return (c->walk&b) ? !dried : false;
7071 }
7072
7073 //Only check the given mapscr*, not its layer 1&2
7074 bool _walkflag_layer(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7075 {
7076 return _walkflag_layer_new(zx, zy, cnt, m, world_w, world_h);
7077 }
7078
7079 bool _walkflag_layer_scrolling(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7080 {
7081 return _walkflag_layer_new(zx, zy, cnt, m, scrolling_region.width, scrolling_region.height);
7082 }
7083
7084 313631 bool _effectflag_layer(int32_t x, int32_t y, int32_t layer, int32_t cnt, bool notLink)
7085 {
7086 DCHECK_LAYER_NEG1_INDEX(layer);
7087 313631 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7088
2/2
✓ Branch 0 taken 1762 times.
✓ Branch 1 taken 311869 times.
313631 if (!m->is_valid()) return false;
7089 311869 return _effectflag_layer(x, y, cnt, m, notLink);
7090 313631 }
7091
7092 377902 bool _effectflag_layer(int32_t x,int32_t y,int32_t cnt, mapscr* m, bool notLink)
7093 {
7094 377902 int max_x = world_w;
7095 377902 int max_y = world_h;
7096
3/4
✓ Branch 0 taken 50002 times.
✓ Branch 1 taken 327900 times.
✓ Branch 2 taken 50002 times.
✗ Branch 3 not taken.
377902 if (!get_qr(qr_LTTPWALK) && !notLink)
7097 {
7098 max_x -= 7;
7099 max_y -= 7;
7100 }
7101
2/4
✓ Branch 0 taken 377902 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 377902 times.
377902 if (x < 0 || y < 0) return false;
7102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 377902 times.
377902 if (x >= max_x) return false;
7103
3/4
✓ Branch 0 taken 1209 times.
✓ Branch 1 taken 376693 times.
✓ Branch 2 taken 1209 times.
✗ Branch 3 not taken.
377902 if (x >= max_x - 8 && cnt == 2) return false;
7104
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 377902 times.
377902 if (y >= max_y) return false;
7105
7106
1/2
✓ Branch 0 taken 377902 times.
✗ Branch 1 not taken.
377902 if (!m) return true;
7107
7108 377902 int pos = COMBOPOS(x%256, y%176);
7109 377902 const newcombo* c = &combobuf[m->data[pos]];
7110
3/4
✓ Branch 0 taken 377502 times.
✓ Branch 1 taken 400 times.
✓ Branch 2 taken 400 times.
✗ Branch 3 not taken.
378302 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7111 377902 int32_t b=1;
7112
7113
2/2
✓ Branch 0 taken 205458 times.
✓ Branch 1 taken 172444 times.
377902 if(x&8) b<<=2;
7114
7115
2/2
✓ Branch 0 taken 157257 times.
✓ Branch 1 taken 220645 times.
377902 if(y&8) b<<=1;
7116
7117
3/4
✓ Branch 0 taken 308913 times.
✓ Branch 1 taken 68989 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 308913 times.
377902 if(((c->walk>>4)&b) && !dried)
7118 308913 return true;
7119
7120
1/2
✓ Branch 0 taken 68989 times.
✗ Branch 1 not taken.
68989 if(cnt==1) return false;
7121
7122 ++pos;
7123
7124 if(!(x&8))
7125 b<<=2;
7126 else
7127 {
7128 c = &combobuf[m->data[pos]];
7129 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7130 b=1;
7131
7132 if(y&8) b<<=1;
7133 }
7134
7135 return ((c->walk>>4)&b) ? !dried : false;
7136 377902 }
7137
7138 812605 bool water_walkflag(int32_t x, int32_t y, int32_t cnt)
7139 {
7140 812605 int max_x = world_w;
7141 812605 int max_y = world_h;
7142
2/2
✓ Branch 0 taken 117367 times.
✓ Branch 1 taken 695238 times.
812605 if (!get_qr(qr_LTTPWALK))
7143 {
7144 695238 max_x -= 7;
7145 695238 max_y -= 7;
7146 695238 }
7147
2/4
✓ Branch 0 taken 812605 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 812605 times.
812605 if (x < 0 || y < 0) return false;
7148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if (x >= max_x) return false;
7149
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
812605 if (x >= max_x - 8 && cnt == 2) return false;
7150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if (y >= max_y) return false;
7151
7152
3/4
✓ Branch 0 taken 16825 times.
✓ Branch 1 taken 795780 times.
✓ Branch 2 taken 795780 times.
✗ Branch 3 not taken.
812605 return water_walkflag(x, y) || (cnt != 1 && water_walkflag(x + 8, y));
7153 812605 }
7154
7155 812605 bool water_walkflag(int32_t x, int32_t y)
7156 {
7157 812605 const newcombo& c = combobuf[MAPCOMBO2(-1, x, y)];
7158 812605 const newcombo& c1 = combobuf[MAPCOMBO2(0, x, y)];
7159 812605 const newcombo& c2 = combobuf[MAPCOMBO2(1, x, y)];
7160
7161 812605 int32_t b=1;
7162
2/2
✓ Branch 0 taken 414677 times.
✓ Branch 1 taken 397928 times.
812605 if(x&8) b<<=2;
7163
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if(y&8) b<<=1;
7164
7165
2/2
✓ Branch 0 taken 26377 times.
✓ Branch 1 taken 786228 times.
812605 if(get_qr(qr_NO_SOLID_SWIM))
7166 {
7167
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 26245 times.
26377 if(c.walk&b)
7168 132 return true;
7169
7170
2/2
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 25953 times.
26245 if(c1.walk&b)
7171 292 return true;
7172
7173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25953 times.
25953 if(c2.walk&b)
7174 return true;
7175 25953 }
7176 else
7177 {
7178
4/4
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 750095 times.
✓ Branch 2 taken 19762 times.
✓ Branch 3 taken 16371 times.
786228 if((c.walk&b) && !iswater_type(c.type))
7179 16371 return true;
7180
7181
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 769840 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
769857 if((c1.walk&b) && !iswater_type(c1.type))
7182 17 return true;
7183
7184
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 769827 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
769840 if((c2.walk&b) && !iswater_type(c2.type))
7185 13 return true;
7186 }
7187
7188 795780 return false;
7189 812605 }
7190
7191 564116 bool hit_walkflag(int32_t x,int32_t y,int32_t cnt)
7192 {
7193
2/2
✓ Branch 0 taken 90999 times.
✓ Branch 1 taken 473117 times.
564116 if(dlevel)
7194
8/8
✓ Branch 0 taken 471712 times.
✓ Branch 1 taken 1405 times.
✓ Branch 2 taken 468517 times.
✓ Branch 3 taken 3195 times.
✓ Branch 4 taken 466857 times.
✓ Branch 5 taken 1660 times.
✓ Branch 6 taken 4199 times.
✓ Branch 7 taken 462658 times.
473117 if(x<32 || y<40 || (x+(cnt-1)*8)>=world_w-32 || y>=world_h-32)
7195 10459 return true;
7196
7197
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 553655 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
553657 if(blockpath && y<((get_qr(qr_LTTPCOLLISION))?80:88))
7198 return true;
7199
7200
8/8
✓ Branch 0 taken 553388 times.
✓ Branch 1 taken 269 times.
✓ Branch 2 taken 553155 times.
✓ Branch 3 taken 233 times.
✓ Branch 4 taken 552946 times.
✓ Branch 5 taken 209 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 552600 times.
553657 if(x<16 || y<16 || (x+(cnt-1)*8)>=world_w-16 || y>=world_h-16)
7201 1057 return true;
7202
7203 // for(int32_t i=0; i<4; i++)
7204
4/4
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 551759 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 805 times.
552600 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7205 36 return true;
7206
7207
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 552564 times.
552564 if (collide_object(x, y,cnt*8, 1))
7208 return true;
7209
7210 552564 return _walkflag(x,y,cnt);
7211 564116 }
7212
7213 12110 bool solpush_walkflag(int32_t x, int32_t y, int32_t cnt, solid_object const* ign)
7214 {
7215 // 16 pixel buffer to account for slopes that are on bordering screens.
7216
4/8
✓ Branch 0 taken 12110 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12110 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12110 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12110 times.
12110 if(x<0 || y<0 || x>=world_w+16 || y>=world_h+16)
7217 return true;
7218
7219 // for(int32_t i=0; i<4; i++)
7220
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12110 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7221 return true;
7222
7223
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
12110 if (collide_object(x, y,cnt*8, 1, ign))
7224 return true;
7225
7226 12110 return _walkflag(x,y,cnt);
7227 12110 }
7228
7229 37837 void map_bkgsfx(bool on)
7230 {
7231
2/2
✓ Branch 0 taken 37816 times.
✓ Branch 1 taken 21 times.
37837 if(on)
7232 {
7233 37816 cont_sfx(hero_scr->oceansfx);
7234
7235
4/4
✓ Branch 0 taken 369 times.
✓ Branch 1 taken 37447 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 54 times.
37816 if(hero_scr->bosssfx && !(game->lvlitems[dlevel]&(1 << li_boss_killed)))
7236 315 cont_sfx(hero_scr->bosssfx);
7237 37816 }
7238 else
7239 {
7240 21 adjust_sfx(hero_scr->oceansfx,128,false);
7241 21 adjust_sfx(hero_scr->bosssfx,128,false);
7242
7243
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 21 times.
135 for(int32_t i=0; i<guys.Count(); i++)
7244 {
7245
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 84 times.
114 if(((enemy*)guys.spr(i))->bgsfx)
7246 84 stop_sfx(((enemy*)guys.spr(i))->bgsfx);
7247 114 }
7248 }
7249 37837 }
7250
7251 239 void toggle_switches(dword flags, bool entry)
7252 {
7253
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 239 times.
239 if(!flags) return; //No flags to toggle
7254
7255 478 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7256 239 toggle_switches(flags, entry, create_screen_handles(scr));
7257 239 });
7258 239 }
7259 53506 void toggle_switches(dword flags, bool entry, const screen_handles_t& screen_handles)
7260 {
7261
2/2
✓ Branch 0 taken 737 times.
✓ Branch 1 taken 52769 times.
53506 if(!flags) return; //No flags to toggle
7262
7263 737 mapscr* m = screen_handles[0].base_scr;
7264 737 int screen = m->screen;
7265 737 bool is_active_screen = is_in_current_region(m);
7266
7267 357489 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
7268 356752 byte togglegrid[176] = {0};
7269 356752 mapscr* scr = rpos_handle.scr;
7270 356752 int lyr = rpos_handle.layer;
7271 356752 int pos = rpos_handle.pos;
7272 356752 newcombo const& cmb = combobuf[scr->data[pos]];
7273
2/2
✓ Branch 0 taken 39424 times.
✓ Branch 1 taken 317328 times.
356752 if(is_active_screen)
7274
1/2
✓ Branch 0 taken 317328 times.
✗ Branch 1 not taken.
472669 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7275
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 155341 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
155341 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7276 }, ctrigSWITCHSTATE);
7277
3/4
✓ Branch 0 taken 356089 times.
✓ Branch 1 taken 663 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2760 times.
356752 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32
7278
2/2
✓ Branch 0 taken 2760 times.
✓ Branch 1 taken 353992 times.
356752 && !(cmb.usrflags & cflag11)) //global state
7279 {
7280
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 2314 times.
2760 if(flags&(1<<cmb.attribytes[0]))
7281 {
7282 2314 set<int32_t> oldData;
7283 //Increment the combo/cset by the attributes
7284 2314 int32_t cmbofs = (cmb.attributes[0]/10000L);
7285 2314 int32_t csofs = (cmb.attributes[1]/10000L);
7286
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 oldData.insert(scr->data[pos]);
7287
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7288 2314 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7289
4/4
✓ Branch 0 taken 1435 times.
✓ Branch 1 taken 879 times.
✓ Branch 2 taken 1197 times.
✓ Branch 3 taken 238 times.
2314 if(entry && (cmb.usrflags&cflag8))
7290 {
7291 238 newcombo const* tmp = &combobuf[scr->data[pos]];
7292
2/4
✓ Branch 0 taken 238 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 238 times.
✗ Branch 3 not taken.
238 while(tmp->can_cycle())
7293 {
7294 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7295 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7296 if(oldData.find(cid) != oldData.end())
7297 break;
7298
7299 scr->data[pos] = cid;
7300 if(!(tmp->animflags & AF_CYCLENOCSET))
7301 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7302 oldData.insert(cid);
7303 tmp = &combobuf[cid];
7304 }
7305 238 }
7306 2314 int32_t cmbid = scr->data[pos];
7307
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 2273 times.
2314 if(combobuf[cmbid].animflags & AF_CYCLE)
7308 {
7309 41 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7310 41 combobuf[cmbid].cur_frame=0;
7311 41 combobuf[cmbid].aclk = 0;
7312
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 combo_caches::drawing.refresh(cmbid);
7313 41 }
7314 2314 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7315
2/2
✓ Branch 0 taken 511 times.
✓ Branch 1 taken 1803 times.
2314 if(cmb.type == cCSWITCH) return; //Switches don't toggle other layers
7316
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2147 times.
2147 for(int32_t lyr2 = 0; lyr2 < 7; ++lyr2) //Toggle same pos on other layers, if flag set
7317 {
7318
2/2
✓ Branch 0 taken 1671 times.
✓ Branch 1 taken 476 times.
2147 if(lyr==lyr2) return;
7319
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 344 times.
476 if(!(cmb.usrflags&(1<<lyr2))) return;
7320
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(togglegrid[pos]&(1<<lyr2)) return;
7321
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
344 mapscr* scr_2 = (lyr2 ? get_scr_layer(screen, lyr2) : m);
7322
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(!scr_2->data[pos]) //Don't increment empty space
7323 return;
7324 344 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7325
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
344 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK) && !(cmb.usrflags & cflag11)
7326 && cmb_2.attribytes[0] < 32 && (flags&(1<<cmb_2.attribytes[0])))
7327 return; //This is a switch/block that will be hit later in the loop!
7328 344 set<int32_t> oldData2;
7329 //Increment the combo/cset by the original cmb's attributes
7330
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 oldData2.insert(scr_2->data[pos]);
7331
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7332 344 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7333
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
344 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7334 {
7335 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7336 while(tmp->can_cycle())
7337 {
7338 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7339 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7340 if(oldData2.find(cid) != oldData2.end())
7341 break;
7342
7343 scr_2->data[pos] = cid;
7344 if(!(tmp->animflags & AF_CYCLENOCSET))
7345 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7346 oldData2.insert(cid);
7347 tmp = &combobuf[cid];
7348 }
7349 }
7350 344 int32_t cmbid2 = scr_2->data[pos];
7351
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(combobuf[cmbid2].animflags & AF_CYCLE)
7352 {
7353 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7354 combobuf[cmbid2].cur_frame=0;
7355 combobuf[cmbid2].aclk = 0;
7356 combo_caches::drawing.refresh(cmbid2);
7357 }
7358 344 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7359 344 }
7360
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 2314 times.
✗ Branch 2 not taken.
2314 }
7361 446 }
7362 356752 });
7363
7364
3/4
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 218 times.
✓ Branch 2 taken 519 times.
✗ Branch 3 not taken.
737 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7365 {
7366 newcombo const& cmb = combobuf[mblock2.bcombo];
7367 if(!(cmb.usrflags & cflag11) && (cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32)
7368 {
7369 if(flags&(1<<cmb.attribytes[0]))
7370 {
7371 //Increment the combo/cset by the attributes
7372 int32_t cmbofs = (cmb.attributes[0]/10000L);
7373 int32_t csofs = (cmb.attributes[1]/10000L);
7374 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7375 mblock2.cs = (mblock2.cs + csofs) & 15;
7376 int32_t cmbid = mblock2.bcombo;
7377 if(combobuf[cmbid].animflags & AF_CYCLE)
7378 {
7379 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7380 combobuf[cmbid].cur_frame=0;
7381 combobuf[cmbid].aclk = 0;
7382 combo_caches::drawing.refresh(cmbid);
7383 }
7384 }
7385 }
7386 }
7387
7388
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 513 times.
737 if (is_active_screen)
7389 {
7390 513 int screen_index_offset = get_region_screen_offset(m->screen);
7391 513 word c = m->numFFC();
7392
2/2
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 513 times.
847 for (int q = 0; q < c; ++q)
7393 {
7394 334 auto ffc_handle = *m->getFFCHandle(q, screen_index_offset);
7395
1/2
✓ Branch 0 taken 334 times.
✗ Branch 1 not taken.
363 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7396
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
29 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7397 }, ctrigSWITCHSTATE);
7398 334 }
7399 513 }
7400 53506 }
7401
7402 1 void toggle_gswitches(int32_t state, bool entry)
7403 {
7404 2 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7405 1 toggle_gswitches(state, entry, create_screen_handles(scr));
7406 1 });
7407 1 }
7408 1 void toggle_gswitches(int32_t state, bool entry, const screen_handles_t& screen_handles)
7409 {
7410 1 bool states[256] = {false};
7411 1 states[state] = true;
7412 1 toggle_gswitches(states, entry, screen_handles);
7413 1 }
7414 15215796 void toggle_gswitches(bool* states, bool entry, const screen_handles_t& screen_handles)
7415 {
7416
1/2
✓ Branch 0 taken 15215796 times.
✗ Branch 1 not taken.
15215796 if(!states) return;
7417
7418 15215796 auto& combo_cache = combo_caches::gswitch;
7419 15215796 mapscr* base_scr = screen_handles[0].base_scr;
7420 15215796 int screen = base_scr->screen;
7421 15215796 bool is_active_screen = is_in_current_region(base_scr);
7422 15215796 byte togglegrid[176] = {0};
7423
2/2
✓ Branch 0 taken 15215796 times.
✓ Branch 1 taken 106510572 times.
121726368 for(int32_t lyr = 0; lyr <= 6; ++lyr)
7424 {
7425 106510572 mapscr* scr = screen_handles[lyr].scr;
7426
2/2
✓ Branch 0 taken 33009762 times.
✓ Branch 1 taken 73500810 times.
106510572 if (!scr)
7427 73500810 continue;
7428
7429
2/2
✓ Branch 0 taken 33009762 times.
✓ Branch 1 taken 5809718112 times.
5842727874 for(int32_t pos = 0; pos < 176; ++pos)
7430 {
7431 5809718112 int cid = scr->data[pos];
7432 5809718112 auto& mini_cmb = combo_cache.minis[cid];
7433
7434
2/2
✓ Branch 0 taken 93442096 times.
✓ Branch 1 taken 5716276016 times.
5809718112 if (is_active_screen)
7435 {
7436
2/2
✓ Branch 0 taken 5716274134 times.
✓ Branch 1 taken 1882 times.
5716276016 if (mini_cmb.trigger_global_state)
7437 {
7438 1882 auto rpos_handle = get_rpos_handle_for_screen(screen, lyr, pos);
7439
1/2
✓ Branch 0 taken 1882 times.
✗ Branch 1 not taken.
3764 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7440
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1882 times.
1882 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7441 }, ctrigSWITCHSTATE);
7442 1882 }
7443 5716276016 }
7444
7445
2/2
✓ Branch 0 taken 40395 times.
✓ Branch 1 taken 5809677717 times.
5809718112 if (!mini_cmb.has_global_state)
7446 5809677717 continue;
7447
7448 40395 newcombo const& cmb = combobuf[cid];
7449
2/4
✓ Branch 0 taken 40395 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40395 times.
40395 if(cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK)
7450 {
7451 if(states[cmb.attribytes[0]])
7452 {
7453 set<int32_t> oldData;
7454 //Increment the combo/cset by the attributes
7455 int32_t cmbofs = (cmb.attributes[0]/10000L);
7456 int32_t csofs = (cmb.attributes[1]/10000L);
7457 oldData.insert(scr->data[pos]);
7458 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7459 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7460 if(entry && (cmb.usrflags&cflag8))
7461 {
7462 newcombo const* tmp = &combobuf[scr->data[pos]];
7463 while(tmp->can_cycle())
7464 {
7465 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7466 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7467 if(oldData.find(cid) != oldData.end())
7468 break;
7469 scr->data[pos] = cid;
7470 if(!(tmp->animflags & AF_CYCLENOCSET))
7471 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7472 oldData.insert(cid);
7473 tmp = &combobuf[cid];
7474 }
7475 }
7476 int32_t cmbid = scr->data[pos];
7477 if(combobuf[cmbid].animflags & AF_CYCLE)
7478 {
7479 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7480 combobuf[cmbid].cur_frame=0;
7481 combobuf[cmbid].aclk = 0;
7482 combo_caches::drawing.refresh(cmbid);
7483 }
7484 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7485 if(cmb.type == cCSWITCH) continue; //Switches don't toggle other layers
7486 for(int32_t lyr2 = 0; lyr2 <= 6; ++lyr2) //Toggle same pos on other layers, if flag set
7487 {
7488 if(lyr==lyr2) continue;
7489 if(!(cmb.usrflags&(1<<lyr2))) continue;
7490 if(togglegrid[pos]&(1<<lyr2)) continue;
7491 mapscr* scr_2 = lyr2 == 0 ? base_scr : get_scr_layer_valid(screen, lyr2);
7492 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7493 continue;
7494 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7495 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK)
7496 && (cmb_2.usrflags & cflag11) && (states[cmb_2.attribytes[0]]))
7497 continue; //This is a switch/block that will be hit later in the loop!
7498 set<int32_t> oldData2;
7499 //Increment the combo/cset by the original cmb's attributes
7500 oldData2.insert(scr_2->data[pos]);
7501 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7502 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7503 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7504 {
7505 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7506 while(tmp->can_cycle())
7507 {
7508 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7509 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7510 if(oldData2.find(cid) != oldData2.end())
7511 break;
7512 scr_2->data[pos] = cid;
7513 if(!(tmp->animflags & AF_CYCLENOCSET))
7514 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7515 oldData2.insert(cid);
7516 tmp = &combobuf[cid];
7517 }
7518 }
7519 int32_t cmbid2 = scr_2->data[pos];
7520 if(combobuf[cmbid2].animflags & AF_CYCLE)
7521 {
7522 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7523 combobuf[cmbid2].cur_frame=0;
7524 combobuf[cmbid2].aclk = 0;
7525 combo_caches::drawing.refresh(cmbid2);
7526 }
7527 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7528 }
7529 }
7530 }
7531 40395 }
7532 33009762 }
7533
7534
4/4
✓ Branch 0 taken 547042 times.
✓ Branch 1 taken 14668754 times.
✓ Branch 2 taken 542298 times.
✓ Branch 3 taken 4744 times.
15215796 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7535 {
7536 4744 newcombo const& cmb = combobuf[mblock2.bcombo];
7537
2/4
✓ Branch 0 taken 4744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4744 times.
✗ Branch 3 not taken.
4744 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && (cmb.usrflags & cflag11))
7538 {
7539 if(states[cmb.attribytes[0]])
7540 {
7541 //Increment the combo/cset by the attributes
7542 int32_t cmbofs = (cmb.attributes[0]/10000L);
7543 int32_t csofs = (cmb.attributes[1]/10000L);
7544 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7545 mblock2.cs = (mblock2.cs + csofs) & 15;
7546 int32_t cmbid = mblock2.bcombo;
7547 if(combobuf[cmbid].animflags & AF_CYCLE)
7548 {
7549 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7550 combobuf[cmbid].cur_frame=0;
7551 combobuf[cmbid].aclk = 0;
7552 combo_caches::drawing.refresh(cmbid);
7553 }
7554 }
7555 }
7556 4744 }
7557
7558
2/2
✓ Branch 0 taken 412941 times.
✓ Branch 1 taken 14802855 times.
15215796 if(is_active_screen)
7559 {
7560 14802855 int screen_index_offset = get_region_screen_offset(screen);
7561 14802855 word c = base_scr->numFFC();
7562
2/2
✓ Branch 0 taken 441793087 times.
✓ Branch 1 taken 14802855 times.
456595942 for (int q = 0; q < c; ++q)
7563 {
7564 441793087 auto ffc_handle = *base_scr->getFFCHandle(q, screen_index_offset);
7565
1/2
✓ Branch 0 taken 441793087 times.
✗ Branch 1 not taken.
442021875 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7566
1/2
✓ Branch 0 taken 228788 times.
✗ Branch 1 not taken.
228788 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7567 }, ctrigSWITCHSTATE);
7568 441793087 }
7569 14802855 }
7570 15215796 }
7571 53267 void toggle_gswitches_load(const screen_handles_t& screen_handles)
7572 {
7573 bool states[256];
7574
2/2
✓ Branch 0 taken 13636352 times.
✓ Branch 1 taken 53267 times.
13689619 for(auto q = 0; q < 256; ++q)
7575 {
7576 13636352 states[q] = game->gswitch_timers[q] != 0;
7577 13636352 }
7578 53267 toggle_gswitches(states, true, screen_handles);
7579 53267 }
7580 14773160 void run_gswitch_timers()
7581 {
7582 14773160 bool states[256] = {false};
7583 14773160 auto& m = game->gswitch_timers.mut_inner();
7584
2/2
✓ Branch 0 taken 3777886720 times.
✓ Branch 1 taken 14773160 times.
3792659880 for(auto it = m.begin(); it != m.end();)
7585 {
7586
2/2
✓ Branch 0 taken 3777886120 times.
✓ Branch 1 taken 600 times.
3777886720 if(it->second > 0)
7587
2/2
✓ Branch 0 taken 599 times.
✓ Branch 1 taken 1 times.
600 if(!--it->second)
7588 {
7589 1 states[it->first] = true;
7590 1 it = m.erase(it);
7591 1 continue;
7592 }
7593 3777886719 ++it;
7594 }
7595 29935688 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7596 15162528 toggle_gswitches(states, false, create_screen_handles(scr));
7597 15162528 });
7598 14773160 }
7599 1116 void onload_gswitch_timers() //Reset all timers that were counting down, no trigger necessary
7600 {
7601
2/2
✓ Branch 0 taken 285696 times.
✓ Branch 1 taken 1116 times.
286812 for(auto q = 0; q < 256; ++q)
7602 {
7603
1/2
✓ Branch 0 taken 285696 times.
✗ Branch 1 not taken.
285696 if(game->gswitch_timers[q] > 0)
7604 game->gswitch_timers[q] = 0;
7605 285696 }
7606 1116 }
7607
7608 /**** View Map ****/
7609
7610 int32_t mapres = 0;
7611 int32_t view_map_show_mode = 3;
7612
7613 124544 bool displayOnMap(int32_t x, int32_t y)
7614 {
7615 124544 int32_t s = (y<<4) + x;
7616 124544 int mi = mapind(cur_map, s);
7617
2/2
✓ Branch 0 taken 67891 times.
✓ Branch 1 taken 56653 times.
124544 if (!(game->maps[mi]&mVISITED))
7618 67891 return false;
7619
7620 // Don't display if not part of DMap
7621
4/4
✓ Branch 0 taken 15628 times.
✓ Branch 1 taken 41025 times.
✓ Branch 2 taken 4655 times.
✓ Branch 3 taken 4311 times.
65619 if(((DMaps[cur_dmap].flags&dmfDMAPMAP) &&
7622
1/2
✓ Branch 0 taken 15628 times.
✗ Branch 1 not taken.
15628 (DMaps[cur_dmap].type != dmOVERW) &&
7623
2/2
✓ Branch 0 taken 12495 times.
✓ Branch 1 taken 3133 times.
15628 !(x >= DMaps[cur_dmap].xoff &&
7624
2/2
✓ Branch 0 taken 8966 times.
✓ Branch 1 taken 3529 times.
12495 x < DMaps[cur_dmap].xoff+8 &&
7625 8966 DMaps[cur_dmap].grid[y]&(128>>(x-DMaps[cur_dmap].xoff)))))
7626 10973 return false;
7627 else
7628 45680 return true;
7629 124544 }
7630
7631 973 void ViewMap()
7632 {
7633 973 ViewingMap = true;
7634
7635 973 BITMAP* mappic = NULL;
7636 static double scales[17] =
7637 {
7638 0.03125, 0.04419, 0.0625, 0.08839, 0.125, 0.177, 0.25, 0.3535,
7639 0.50, 0.707, 1.0, 1.414, 2.0, 2.828, 4.0, 5.657, 8.0
7640 };
7641
7642 // Cursor position for hero, in absolute map coordinates.
7643 973 int32_t lx = ((cur_screen & 15) << 8) + HeroX() + 8;
7644 973 int32_t ly = ((cur_screen >> 4) * 176) + HeroY() + 8;
7645
7646 int32_t px;
7647 int32_t py;
7648
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 973 times.
973 if (is_in_scrolling_region())
7649 {
7650 // Center the player on the middle of the map view.
7651 px = (16*256/2 - lx) * 2;
7652 py = (8*176/2 - ly) * 2;
7653 }
7654 else
7655 {
7656 // Center the current screen on the middle of the map view.
7657 973 px = ((8-(cur_screen&15)) << 9) - 256;
7658 973 py = ((4-(cur_screen>>4)) * 352) - 176;
7659 }
7660
7661 973 int32_t sc = 6;
7662
7663 973 bool done=false, redraw=true;
7664
7665 973 mappic = create_bitmap_ex(8,(256*16)>>mapres,(176*8)>>mapres);
7666
7667
1/2
✓ Branch 0 taken 973 times.
✗ Branch 1 not taken.
973 if(!mappic)
7668 {
7669 enter_sys_pal();
7670 jwin_alert("View Map","Not enough memory.",NULL,NULL,"OK",NULL,13,27,get_zc_font(font_lfont));
7671 exit_sys_pal();
7672 return;
7673 }
7674
7675 973 clear_to_color(mappic, WHITE);
7676
7677 973 auto prev_viewport = viewport;
7678 973 viewport.x = 0;
7679 973 viewport.y = 0;
7680
7681 // draw the map
7682 973 BITMAP* screen_bmp = create_bitmap_ex(8, 256, 176);
7683 973 combotile_add_x = 256;
7684 973 combotile_add_y = 0;
7685
2/2
✓ Branch 0 taken 7784 times.
✓ Branch 1 taken 973 times.
8757 for(int32_t y=0; y<8; y++)
7686 {
7687
2/2
✓ Branch 0 taken 124544 times.
✓ Branch 1 taken 7784 times.
132328 for(int32_t x=0; x<16; x++)
7688 {
7689
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 78864 times.
124544 if (!displayOnMap(x, y))
7690 78864 continue;
7691
7692 45680 int screen = map_scr_xy_to_index(x, y);
7693 45680 auto scrs = loadscr2(screen);
7694 45680 mapscr* scr = &scrs[0];
7695
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if (!scr->is_valid())
7696 continue;
7697
7698 screen_handles_t screen_handles;
7699
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 319760 times.
365440 for (int i = 0; i <= 6; i++)
7700
3/4
✓ Branch 0 taken 319760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103061 times.
✓ Branch 3 taken 216699 times.
319760 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
7701
7702 45680 int xx = 0;
7703 45680 int yy = -playing_field_offset;
7704
7705
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 45660 times.
45680 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7706 {
7707
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7708
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7709 20 }
7710
7711
2/2
✓ Branch 0 taken 175 times.
✓ Branch 1 taken 45505 times.
45680 if(XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
7712 {
7713
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7714
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_ffc_layer(screen_bmp, -3, screen_handles[0], xx, yy);
7715 175 }
7716
7717
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if(lenscheck(scr,0)) putscr(scr, screen_bmp, 0, 0);
7718
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 0, screen_handles[0], xx, yy);
7719
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[1], xx, yy);
7720
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 1, screen_handles[0], xx, yy);
7721
7722
2/2
✓ Branch 0 taken 45660 times.
✓ Branch 1 taken 20 times.
45680 if(!XOR((scr->flags7&fLAYER2BG), DMaps[cur_dmap].flags&dmfLAYER2BG))
7723 {
7724
1/2
✓ Branch 0 taken 45660 times.
✗ Branch 1 not taken.
45660 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7725
1/2
✓ Branch 0 taken 45660 times.
✗ Branch 1 not taken.
45660 do_ffc_layer(screen_bmp, 2, screen_handles[0], xx, yy);
7726 45660 }
7727
7728
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 putscrdoors(scr, screen_bmp, xx, yy);
7729
2/2
✓ Branch 0 taken 41678 times.
✓ Branch 1 taken 4002 times.
45680 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
7730 {
7731
1/2
✓ Branch 0 taken 41678 times.
✗ Branch 1 not taken.
41678 do_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7732
2/2
✓ Branch 0 taken 1782 times.
✓ Branch 1 taken 39896 times.
41678 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
7733 {
7734
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[1], xx, yy);
7735
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[2], xx, yy);
7736 1782 }
7737 41678 }
7738
7739
2/2
✓ Branch 0 taken 45505 times.
✓ Branch 1 taken 175 times.
45680 if(!XOR((scr->flags7&fLAYER3BG), DMaps[cur_dmap].flags&dmfLAYER3BG))
7740 {
7741
1/2
✓ Branch 0 taken 45505 times.
✗ Branch 1 not taken.
45505 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7742
1/2
✓ Branch 0 taken 45505 times.
✗ Branch 1 not taken.
45505 do_ffc_layer(screen_bmp, 3, screen_handles[0], xx, yy);
7743 45505 }
7744
7745
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[4], xx, yy);
7746
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 4, screen_handles[0], xx, yy);
7747
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7748
2/2
✓ Branch 0 taken 5784 times.
✓ Branch 1 taken 39896 times.
45680 if(get_qr(qr_OVERHEAD_COMBOS_L1_L2))
7749 {
7750
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[1], xx, yy);
7751
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[2], xx, yy);
7752 5784 }
7753
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[5], xx, yy);
7754
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 5, screen_handles[0], xx, yy);
7755
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45680 times.
45680 if(replay_version_check(40))
7756 do_ffc_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7757
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[6], xx, yy);
7758
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 6, screen_handles[0], xx, yy);
7759
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 7, screen_handles[0], xx, yy);
7760
7761
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 stretch_blit(screen_bmp, mappic, 0, 0, 256, 176, x<<(8-mapres), (y*176)>>mapres, 256>>mapres, 176>>mapres);
7762
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
45680 }
7763 7784 }
7764
7765 973 viewport = prev_viewport;
7766 973 combotile_add_x = 0;
7767 973 combotile_add_y = 0;
7768
7769 973 destroy_bitmap(screen_bmp);
7770 973 clear_keybuf();
7771 973 pause_all_sfx();
7772
7773 // view it
7774 973 int32_t delay = 0;
7775
7776 973 do
7777 {
7778
2/2
✓ Branch 0 taken 178717 times.
✓ Branch 1 taken 29891 times.
208608 if (replay_version_check(0, 11))
7779 29891 load_control_state();
7780
7781 208608 int32_t step = int32_t(16.0/scales[sc]);
7782 208608 step = (step>>1) + (step&1);
7783 208608 bool r = cRbtn();
7784
7785
1/2
✓ Branch 0 taken 208608 times.
✗ Branch 1 not taken.
208608 if(cLbtn())
7786 {
7787 step <<= 2;
7788 delay = 0;
7789 }
7790
7791
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 208608 times.
208608 if(r)
7792 {
7793 if(rUp())
7794 {
7795 py+=step;
7796 redraw=true;
7797 }
7798
7799 if(rDown())
7800 {
7801 py-=step;
7802 redraw=true;
7803 }
7804
7805 if(rLeft())
7806 {
7807 px+=step;
7808 redraw=true;
7809 }
7810
7811 if(rRight())
7812 {
7813 px-=step;
7814 redraw=true;
7815 }
7816 }
7817 else
7818 {
7819
2/2
✓ Branch 0 taken 193729 times.
✓ Branch 1 taken 14879 times.
208608 if(Up())
7820 {
7821 14879 py+=step;
7822 14879 redraw=true;
7823 14879 }
7824
7825
2/2
✓ Branch 0 taken 193574 times.
✓ Branch 1 taken 15034 times.
208608 if(Down())
7826 {
7827 15034 py-=step;
7828 15034 redraw=true;
7829 15034 }
7830
7831
2/2
✓ Branch 0 taken 182159 times.
✓ Branch 1 taken 26449 times.
208608 if(Left())
7832 {
7833 26449 px+=step;
7834 26449 redraw=true;
7835 26449 }
7836
7837
2/2
✓ Branch 0 taken 182774 times.
✓ Branch 1 taken 25834 times.
208608 if(Right())
7838 {
7839 25834 px-=step;
7840 25834 redraw=true;
7841 25834 }
7842 }
7843
7844
2/2
✓ Branch 0 taken 187444 times.
✓ Branch 1 taken 21164 times.
208608 if(delay)
7845 21164 --delay;
7846 else
7847 {
7848 187444 bool a = cAbtn();
7849 187444 bool b = cBbtn();
7850
7851
3/4
✓ Branch 0 taken 1721 times.
✓ Branch 1 taken 185723 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1721 times.
187444 if(a && !b)
7852 {
7853
1/2
✓ Branch 0 taken 1721 times.
✗ Branch 1 not taken.
1721 sc=zc_min(sc+1,16);
7854 1721 delay=8;
7855 1721 redraw=true;
7856 1721 }
7857
7858
3/4
✓ Branch 0 taken 927 times.
✓ Branch 1 taken 186517 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 927 times.
187444 if(b && !a)
7859 {
7860
2/2
✓ Branch 0 taken 926 times.
✓ Branch 1 taken 1 times.
927 sc=zc_max(sc-1,0);
7861 927 delay=8;
7862 927 redraw=true;
7863 927 }
7864 }
7865
7866
2/2
✓ Branch 0 taken 208597 times.
✓ Branch 1 taken 11 times.
208608 if(rPbtn())
7867 11 --view_map_show_mode;
7868
7869 208608 px = vbound(px,-4096,4096);
7870 208608 py = vbound(py,-1408,1408);
7871
7872 208608 double scale = scales[sc];
7873
7874
2/2
✓ Branch 0 taken 72838 times.
✓ Branch 1 taken 135770 times.
208608 if(!redraw)
7875 {
7876 135770 blit(scrollbuf_old,framebuf,256,0,0,0,256,232);
7877 135770 }
7878 else
7879 {
7880 72838 clear_to_color(framebuf,BLACK);
7881 145676 stretch_blit(mappic,framebuf,0,0,mappic->w,mappic->h,
7882 72838 int32_t(256+(int64_t(px)-mappic->w)*scale)/2,int32_t(224+(int64_t(py)-mappic->h)*scale)/2,
7883 72838 int32_t(mappic->w*scale),int32_t(mappic->h*scale));
7884
7885 72838 blit(framebuf,scrollbuf_old,0,0,256,0,256,232);
7886 72838 redraw=false;
7887 }
7888
7889 208608 int32_t x = int32_t(256+(px-((2048-int64_t(lx))*2))*scale)/2;
7890 208608 int32_t y = int32_t(224+(py-((704-int64_t(ly))*2))*scale)/2;
7891
7892
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 201142 times.
208608 if(view_map_show_mode&1)
7893 {
7894 201142 line(framebuf,x-7,y-7,x+7,y+7,(frame&3)+252);
7895 201142 line(framebuf,x+7,y-7,x-7,y+7,(frame&3)+252);
7896 201142 }
7897
7898
3/4
✓ Branch 0 taken 5600 times.
✓ Branch 1 taken 203008 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5600 times.
208608 if(view_map_show_mode&2 || r)
7899 203008 textprintf_ex(framebuf,font,224,216,WHITE,BLACK,"%1.2f",scale);
7900
7901
1/2
✓ Branch 0 taken 208608 times.
✗ Branch 1 not taken.
208608 if(r)
7902 {
7903 textprintf_ex(framebuf,font,0,208,WHITE,BLACK,"m: %d %d",px,py);
7904 textprintf_ex(framebuf,font,0,216,WHITE,BLACK,"x: %d %d",x,y);
7905 }
7906
7907 208608 advanceframe(false, false);
7908
2/2
✓ Branch 0 taken 29891 times.
✓ Branch 1 taken 178717 times.
208608 if (replay_version_check(11))
7909 178717 load_control_state();
7910
7911
2/2
✓ Branch 0 taken 207636 times.
✓ Branch 1 taken 972 times.
208608 if (getInput(btnS, INPUT_PRESS | INPUT_IGNORE_DISABLE))
7912 972 done = true;
7913
7914
2/2
✓ Branch 0 taken 207635 times.
✓ Branch 1 taken 973 times.
417216 }
7915
2/2
✓ Branch 0 taken 972 times.
✓ Branch 1 taken 207636 times.
208608 while(!done && !Quit);
7916
7917 973 ViewingMap = false;
7918 973 destroy_bitmap(mappic);
7919 973 resume_all_sfx();
7920 973 }
7921
7922 1075 int32_t onViewMap()
7923 {
7924
4/6
✓ Branch 0 taken 1075 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1075 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✓ Branch 5 taken 973 times.
1075 if(Playing && cur_screen<128 && DMaps[cur_dmap].flags&dmfVIEWMAP)
7925 {
7926 973 clear_to_color(framebuf,BLACK);
7927 973 textout_centre_ex(framebuf,font,"Drawing map...",128,108,WHITE,BLACK);
7928 973 advanceframe(true);
7929 973 ViewMap();
7930 973 }
7931
7932 1075 return D_O_K;
7933 }
7934
7935 35757403 bool isGrassType(int32_t type)
7936 {
7937
2/2
✓ Branch 0 taken 35080991 times.
✓ Branch 1 taken 676412 times.
35757403 switch(type)
7938 {
7939 case cTALLGRASS:
7940 case cTALLGRASSNEXT:
7941 case cTALLGRASSTOUCHY:
7942 676412 return true;
7943 }
7944
7945 35080991 return false;
7946 35757403 }
7947
7948 20914 bool isFlowersType(int32_t type)
7949 {
7950
2/2
✓ Branch 0 taken 16574 times.
✓ Branch 1 taken 4340 times.
20914 switch(type)
7951 {
7952 case cFLOWERS:
7953 case cFLOWERSTOUCHY:
7954 4340 return true;
7955 }
7956
7957 16574 return false;
7958 20914 }
7959
7960 bool isGenericType(int32_t type)
7961 {
7962 switch(type)
7963 {
7964 case cTRIGGERGENERIC:
7965 return true;
7966 }
7967
7968 return false;
7969 }
7970
7971 26056 bool isBushType(int32_t type)
7972 {
7973
2/2
✓ Branch 0 taken 20914 times.
✓ Branch 1 taken 5142 times.
26056 switch(type)
7974 {
7975 case cBUSH:
7976 case cBUSHNEXT:
7977 case cBUSHTOUCHY:
7978 case cBUSHNEXTTOUCHY:
7979
7980 5142 return true;
7981 }
7982
7983 20914 return false;
7984 26056 }
7985
7986 bool isSlashType(int32_t type)
7987 {
7988 switch(type)
7989 {
7990 case cSLASH:
7991 case cSLASHITEM:
7992 case cSLASHTOUCHY:
7993 case cSLASHITEMTOUCHY:
7994 case cSLASHNEXT:
7995 case cSLASHNEXTITEM:
7996 case cSLASHNEXTTOUCHY:
7997 case cSLASHNEXTITEMTOUCHY:
7998 return true;
7999 }
8000
8001 return false;
8002 }
8003
8004 15695 bool isCuttableNextType(int32_t type)
8005 {
8006
2/2
✓ Branch 0 taken 9788 times.
✓ Branch 1 taken 5907 times.
15695 switch(type)
8007 {
8008 case cSLASHNEXT:
8009 case cSLASHNEXTITEM:
8010 case cTALLGRASSNEXT:
8011 case cBUSHNEXT:
8012 case cSLASHNEXTTOUCHY:
8013 case cSLASHNEXTITEMTOUCHY:
8014 case cBUSHNEXTTOUCHY:
8015 5907 return true;
8016 }
8017
8018 9788 return false;
8019 15695 }
8020
8021 17546 bool isTouchyType(int32_t type)
8022 {
8023
2/2
✓ Branch 0 taken 6050 times.
✓ Branch 1 taken 11496 times.
17546 switch(type)
8024 {
8025 case cSLASHTOUCHY:
8026 case cSLASHITEMTOUCHY:
8027 case cBUSHTOUCHY:
8028 case cFLOWERSTOUCHY:
8029 case cTALLGRASSTOUCHY:
8030 case cSLASHNEXTTOUCHY:
8031 case cSLASHNEXTITEMTOUCHY:
8032 case cBUSHNEXTTOUCHY:
8033 11496 return true;
8034 }
8035
8036 6050 return false;
8037 17546 }
8038
8039 29332374 bool isCuttableType(int32_t type)
8040 {
8041
2/2
✓ Branch 0 taken 28883109 times.
✓ Branch 1 taken 449265 times.
29332374 switch(type)
8042 {
8043 case cSLASH:
8044 case cSLASHITEM:
8045 case cBUSH:
8046 case cFLOWERS:
8047 case cTALLGRASS:
8048 case cTALLGRASSNEXT:
8049 case cSLASHNEXT:
8050 case cSLASHNEXTITEM:
8051 case cBUSHNEXT:
8052
8053 case cSLASHTOUCHY:
8054 case cSLASHITEMTOUCHY:
8055 case cBUSHTOUCHY:
8056 case cFLOWERSTOUCHY:
8057 case cTALLGRASSTOUCHY:
8058 case cSLASHNEXTTOUCHY:
8059 case cSLASHNEXTITEMTOUCHY:
8060 case cBUSHNEXTTOUCHY:
8061 449265 return true;
8062 }
8063
8064 28883109 return false;
8065 29332374 }
8066
8067 17322 bool isCuttableItemType(int32_t type)
8068 {
8069
2/2
✓ Branch 0 taken 424 times.
✓ Branch 1 taken 16898 times.
17322 switch(type)
8070 {
8071 case cSLASHITEM:
8072 case cBUSH:
8073 case cFLOWERS:
8074 case cTALLGRASS:
8075 case cTALLGRASSNEXT:
8076 case cSLASHNEXTITEM:
8077 case cBUSHNEXT:
8078
8079 case cSLASHITEMTOUCHY:
8080 case cBUSHTOUCHY:
8081 case cFLOWERSTOUCHY:
8082 case cTALLGRASSTOUCHY:
8083 case cSLASHNEXTITEMTOUCHY:
8084 case cBUSHNEXTTOUCHY:
8085 16898 return true;
8086 }
8087
8088 424 return false;
8089 17322 }
8090
8091 66 bool is_push(mapscr* m, int32_t pos)
8092 {
8093
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(m->sflag[pos]))
8094 return true;
8095 66 newcombo const& cmb = combobuf[m->data[pos]];
8096
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(cmb.flag))
8097 return true;
8098
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 52 times.
66 if(cmb.type == cPUSHBLOCK)
8099 14 return true;
8100
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
52 if(cmb.type == cSWITCHHOOK && (cmb.usrflags&cflag7))
8101 return true; //Counts as 'pushblock' flag
8102 52 return false;
8103 66 }
8104
8105 414 static std::map<int, screen_state_t> screen_states;
8106
8107 35854 std::map<int, screen_state_t>& get_screen_states()
8108 {
8109 35854 return screen_states;
8110 }
8111
8112 44182923 screen_state_t& get_screen_state(int screen)
8113 {
8114 44182923 return screen_states[screen];
8115 }
8116
8117 575 void clear_screen_states()
8118 {
8119 575 screen_states.clear();
8120 575 }
8121
8122 1439 void screen_item_set_state(int screen, ScreenItemState state)
8123 {
8124 1439 get_screen_state(screen).item_state = state;
8125 1439 }
8126
8127 37019 void mark_visited(int screen)
8128 {
8129
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 36544 times.
37019 if (screen < 0x80)
8130 {
8131
2/2
✓ Branch 0 taken 24611 times.
✓ Branch 1 taken 11933 times.
36544 if(DMaps[cur_dmap].flags&dmfVIEWMAP)
8132 11933 game->maps[mapind(cur_map, screen)] |= mVISITED;
8133
8134 36544 markBmap(-1, screen);
8135 36544 }
8136 37019 }
8137